【问题标题】:A method returns null object when called from onCreate but returns correct value in onClick method一个方法从 onCreate 调用时返回 null 对象,但在 onClick 方法中返回正确的值
【发布时间】:2018-03-03 07:23:40
【问题描述】:

我在我的应用程序中使用 wuapnjie/StickerView library,当我在 onCreate 方法中调用该方法时,StickerView 类中的函数 getCurrentSticker 之一返回空对象引用,但从任何 onClick 方法调用时都能正常工作。您的任何专业知识都会非常有帮助。谢谢。

当我尝试在 runOnUiThread 中的单独线程中运行代码时,有时它可以工作,有时不能。为什么有些代码会在某个时候起作用,而不是其他时候。我很迷茫。下面是在 onClick 方法中工作而不在 onCreate 方法中工作的代码。

当我在下面的代码中从 onCreate 调用 addStickerNow 时,它返回空值。在 onClick 方法中,它返回的是实际值。

public class MainActiviy extends AppCompatActivity
{
private StickerView stickerView;
private Button button;
LinearLayout layout;

@Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    layout = findViewById(R.id.lnr_draw);
    stickerView = (StickerView) findViewById(R.id.sticker_view);
    button = (Button) findViewById(R.id.button3);
    addStickerNow(); //It's not working.
}

public void onButtonClicked(View view)
{
  addStickerNow(); //It's working.
}

public void addStickerNow()
{
stickerView.addSticker(
        new TextSticker(getApplicationContext())
                .setText("TEXT")
                .setMaxTextSize(70)
                .setTextAlign(Layout.Alignment.ALIGN_CENTER)
                .setMinTextSize(100)
        , Sticker.Position.TOP);

 int test = 1;  //1st breakpoint
 Sticker sticker = stickerView.getCurrentSticker();  // 2nd breakpoint
 int test2 = 1; //3rd breakpoint
 }
}

我尝试按照 Mr.Hyde 的建议调试应用,发现从 onCreate 和 onClick 调用 addStickerNow 时出现以下差异。

*1st breakpoint, when called from onCreate
this = {MainActivity@4424} 
stickerView = {StickerView@4427} "com.xiaopo.flying.sticker.StickerView{7b55d6d V.E...... ......I. 0,0-0,0 #7f070071 app:id/sticker_view}"

1st breakpoint, when called from onClick
this = {MainActivity@4424} 
stickerView = {StickerView@4427} "com.xiaopo.flying.sticker.StickerView{7b55d6d V.E...... ......ID 0,160-720,760 #7f070071 app:id/sticker_view}"*

这里的主要区别是 StickerView 的 RectF 在从 onCreate 调用时是 0,0-0,0 而从 onClick 调用时是 0,160-720,760。所以它与布局创建有关。

布局文件如下。

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:id="@+id/parent_layout"
    tools:context="e.venkihero.stickerviewtest.MainActivity">

    <LinearLayout
        android:id="@+id/lnr_draw"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_weight="1.0"
        android:gravity="center"
        android:orientation="vertical">

        <com.xiaopo.flying.sticker.StickerView
            android:id="@+id/sticker_view"
            android:layout_width="fill_parent"
            android:layout_height="300dp"
            android:layout_gravity="center"

            app:showIcons="true">



            <ImageView
                android:id="@+id/img_bg1"
                android:layout_width="fill_parent"
                android:layout_height="fill_parent"
                android:background="@android:color/white"
                android:scaleType="fitXY" />

        </com.xiaopo.flying.sticker.StickerView>
    </LinearLayout>

    <Button
        android:id="@+id/button3"
        android:layout_width="100dp"
        android:layout_height="100dp"
        android:onClick="onButtonClicked"
        android:clickable="true" />

</LinearLayout>

如果有人能解释为什么这段代码(位于顶部)在 onClick 方法中运行良好,但在 onCreate 方法中返回空对象引用,那将非常有帮助。谢谢。

【问题讨论】:

  • 请添加您的MainActivity 的一部分。特别是OnCreate.
  • 添加代码你是如何从 MainActivity OnCreate 方法调用它的?
  • @Mr.Hyde 我最初添加的第一段代码仅来自 onCreate。现在我对其进行了编辑以查看它是从 onCreate 调用的。 (注意:这不是我实际的 MainActivity,但我正在尝试这样做。当我从 onCreate 调用 addStickerNow 时,返回 Null 指针,但是当它从 onClick 方法(onButtonClicked)调用时,它返回实际值。
  • @MilanHirpara 请立即查看更新后的代码
  • @Mr.Hyde Nitinkumar 的以下回答有效。这一切都来自您调试应用程序的建议。非常感谢。

标签: android onclick nullreferenceexception oncreate


【解决方案1】:

似乎 StickerView 取决于您的整体布局来绘制自己。由于在 onCreate 你的布局没有绘制在你的 Activity 上,所以你的 StickerView 的 Rect 都是 0。

onCreate 中添加以下代码,等待布局被绘制,然后调用您的 addSticker 方法。

ViewTreeObserver vto = yourLayout.getViewTreeObserver();

vto.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
    @Override
    public void onGlobalLayout() {                
        vto.removeOnGlobalLayoutListener(this)
        addStickerNow()
    }
});

【讨论】:

  • 这正是我所需要的。有效。感谢您的回答。我对 Android 开发非常陌生,所以不知道。这是一次很好的学习经历。
  • 我很想支持你的回答.. 但是 stackoverflow 不允许我这样做,因为我没有 15 个声望点。为什么会有这种奇怪的规则我不知道。一旦我获得 15 点声望点,我就会这样做。谢谢。
猜你喜欢
  • 2012-10-21
  • 2016-08-07
  • 1970-01-01
  • 2016-02-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-06-07
  • 1970-01-01
相关资源
最近更新 更多