【问题标题】:null object reference error in android while using a thread [duplicate]使用线程时android中的空对象引用错误[重复]
【发布时间】:2017-01-26 09:24:01
【问题描述】:

我正在尝试动态更改按钮颜色,因此我创建了一个线程来执行此操作,但出现以下错误

W/System.err: java.lang.NullPointerException: 尝试调用 虚拟方法 'void android.widget.Button.setBackgroundColor(int)' on 空对象引用

以下是我的代码

public class MainActivity extends AppCompatActivity implements View.OnClickListener,Runnable {
Button b1, b2, b3, b4;
Random r = new Random();
int random_selection;
Thread t1;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    b1 = (Button) findViewById(R.id.button);
    b2 = (Button) findViewById(R.id.button2);
    b3 = (Button) findViewById(R.id.button3);
    b4 = (Button) findViewById(R.id.button4);
    b1.setBackgroundColor(Color.BLUE);
    b2.setBackgroundColor(Color.BLUE);
    b3.setBackgroundColor(Color.BLUE);
    b4.setBackgroundColor(Color.BLUE);
    b1.setOnClickListener(this);
    b2.setOnClickListener(this);
    b3.setOnClickListener(this);
    b4.setOnClickListener(this);
    delay(7000);

    main();


}

private void main() {
    // Thread t1 = new Thread(new MainActivity());
    // this wi run() function
    t1 = new Thread(new MainActivity());
    System.out.println("inside main");
    t1.start();
    System.out.println("after t1.start()");

}

@Override
public void onClick(View v) {

    switch (v.getId()) {

        case R.id.button:

            break;
        case R.id.button2:

            break;
        case R.id.button3:

            break;
        case R.id.button4:

            break;


        default:
            android.widget.Toast.makeText(getBaseContext(), "Wrong Selection",
                    android.widget.Toast.LENGTH_SHORT).show();
            break;
    }

}


public int randomgen() {

    random_selection = r.nextInt(4) + 1;
    return random_selection;
}

public void delay(int t) {
    try {
        Thread.sleep(t);
    } catch (InterruptedException ex) {
        Thread.currentThread().interrupt();
    }
}


//@Override•
public void run() {
    try {
        System.out.println("inside run");
        int x, count = 0;
        for (; ; ) {

            count = count + 1;
            x = randomgen();
            //     android.widget.Toast.makeText(getBaseContext(), x,android.widget.Toast.LENGTH_SHORT).show();
            if (x == 1) {
              b1.setBackgroundColor(Color.BLACK);
                delay(5000);
              b1.setBackgroundResource(android.R.drawable.btn_default);
                System.out.println(this.b1);
            } else if (x == 2) {
              b2.setBackgroundColor(Color.BLACK);
                delay(5000);
              b2.setBackgroundResource(android.R.drawable.btn_default);
                System.out.println(this.b2);
            } else if (x == 3) {
              b3.setBackgroundColor(Color.BLACK);
                delay(5000);
              b3.setBackgroundResource(android.R.drawable.btn_default);
                System.out.println(this.b3);
            } else if (x == 4) {
              b4.setBackgroundColor(Color.BLACK);
                delay(5000);
              b4.setBackgroundResource(android.R.drawable.btn_default);
                System.out.println(this.b4);

            }

            if (count == 4) {
                break;
            }
        }

    } catch (Exception e) {
        System.out.println("inside catch");
        e.printStackTrace();
    }
}

}

 <?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/activity_main"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context="com.hellotape.hdl.test_bomber.MainActivity">

    <Button
        android:text="Button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentTop="true"
        android:layout_alignParentStart="true"
        android:layout_marginStart="51dp"
        android:layout_marginTop="127dp"
        android:id="@+id/button"
        android:visibility="visible" />

    <Button
        android:text="Button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignBottom="@+id/button"
        android:layout_alignParentEnd="true"
        android:layout_marginEnd="52dp"
        android:id="@+id/button2" />

    <Button
        android:text="Button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@+id/button"
        android:layout_alignEnd="@+id/button"
        android:layout_marginTop="113dp"
        android:id="@+id/button3" />

    <Button
        android:text="Button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignBottom="@+id/button3"
        android:layout_alignEnd="@+id/button2"
        android:id="@+id/button4"
        android:elevation="5dp" />

</RelativeLayout>

调试的时候发现一进入线程t1,按钮变量b1,b2,b3,b4就变成了null,这个错误是什么原因以及如何解决?

【问题讨论】:

  • 也添加您的 xml 代码
  • @MikeM。如何解决这个问题

标签: java android multithreading


【解决方案1】:

您有 2 个 MainActivity 对象。首先,您的应用程序将启动 onCreate() 并且您的字段将被初始化。然后你调用new Thread(new MainActivity()),这意味着你创建了一个MainActivity 的新对象。然后您访问线程的未初始化按钮,因为如果您调用new MainActivityonCreate() 将不会被调用。

【讨论】:

    【解决方案2】:

    基本上 MainActivity 在 UI 线程中运行,所有按钮都可以在 UI 线程中访问。由于我们启动了新线程并且我们正在尝试修改按钮属性,因此按钮将无法访问。如果我们要修改任何 UI 元素,我们必须使用 Handler 或 runOnUiThread 来完成,如下所示

    someActivity.runOnUiThread(new Runnable() {
            @Override
            public void run() {
               // Code here will run in UI thread
            }
    });
    

    new Handler().post(new Runnable() {
        @Override
        public void run() {
            // Code here will run in UI thread
        }
    });
    

    在 run() 中更新 UI 元素。

    【讨论】:

      猜你喜欢
      • 2013-08-22
      • 1970-01-01
      • 1970-01-01
      • 2022-08-18
      • 2016-07-04
      • 1970-01-01
      • 2018-12-31
      • 2016-10-04
      • 2017-01-26
      相关资源
      最近更新 更多