如何从 android 中的 AsyncTask 获取 UI 引用

How do I get UI reference from AsyncTask in android

我正在尝试在 android 中学习多线程,尽管当我在 Logcat window 上打印数据时我的代码工作正常,但我的应用程序崩溃并在任何时候给我一个空点异常我尝试从异步任务更新组件。

它给我以下错误

 java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.TextView.append(java.lang.CharSequence)' on a null object reference
    at com.shivam.asynctasks.MainActivity.logm(MainActivity.java:41)

第 41 行

textView.append(message + "\n");

我的代码

    public class MainActivity extends AppCompatActivity {

    Button button ;
    TextView textView;
    String TAG = "MyTag";

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

        button=findViewById(R.id.button);
        textView=findViewById(R.id.TextView);

        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                String TAG ="MyTag";
                Log.d(TAG,"OnClick Thread Started");

                MyTask mytask =new MyTask();
                mytask.execute("Red","Black","Yellow","Blue","Orange");
            }
        });
    }


    public void logm(String message) {
        Log.d(TAG, message);
        textView.append(message + "\n");
    }
}

class MyTask extends AsyncTask<String,String,String>{

    @Override
    protected String doInBackground(String... strings) {
        String TAG = "MyTag";

        for (String value :
                strings) {
            try {
                Thread.sleep(3000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

            Log.d(TAG, "do in Background  : "+value);
            publishProgress(value);

        }

        return null;
    }

    @Override
    protected void onProgressUpdate(String... values) {
        super.onProgressUpdate(values);
         MainActivity mainActivity =new MainActivity();

        for (String color : values) {

            mainActivity.logm(color);
        }
    }
}

您需要参考您的 activity 而不是创建新的。在这里你可以看到。

import android.os.AsyncTask;

public class MainActivity extends AppCompatActivity {

    Button button ;
    TextView textView;
    String TAG = "MyTag";

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

        button=findViewById(R.id.button);
        textView=findViewById(R.id.TextView);

        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                String TAG ="MyTag";
                Log.d(TAG,"OnClick Thread Started");

                MyTask mytask =new MyTask(this);
                mytask.execute("Red","Black","Yellow","Blue","Orange");
            }
        });
    }


    public void logm(String message) {
        Log.d(TAG, message);
        textView.append(message + "\n");
    }
}

class MyTask extends AsyncTask<String,String,String> {
    WeakReference<MainActivity> mainActivityRef;
    public MyTask(MainActivity activity){
        mainActivityRef = new WeakReference<MainActivity>(activity);
    }
    @Override
    protected String doInBackground(String... strings) {
        String TAG = "MyTag";

        for (String value :
                strings) {
            try {
                Thread.sleep(3000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

            Log.d(TAG, "do in Background  : "+value);
            publishProgress(value);

        }

        return null;
    }

    @Override
    protected void onProgressUpdate(String... values) {
        super.onProgressUpdate(values);
        MainActivity mainActivity = mainActivityRef.get();

        for (String color : values) {
            mainActivity.logm(color);
        }
    }

您收到错误是因为您在未启动 textView 的 onProgressUpdate() 方法中再次创建 mainactivity class 的实例。这就是为什么您在未启动 textview 字段时收到空指针异常的原因。

您的问题有一个简单的解决方案。 onProgressUpdate() 方法在主 UI 线程上运行,您可以访问 onProgressUpdate() 方法内的 textview 变量。所以只需执行以下操作:

@Override
protected void onProgressUpdate(String... values) {
    super.onProgressUpdate(values);
     MainActivity mainActivity =new MainActivity();

    for (String color : values) {

        textView.append(color + "\n");
    }
}