如何从 android 中的 AsyncTask 获取 UI 参考
Posted
技术标签:
【中文标题】如何从 android 中的 AsyncTask 获取 UI 参考【英文标题】:How do I get UI reference from AsyncTask in android 【发布时间】:2020-08-28 19:38:54 【问题描述】:我正在尝试在 android 中学习多线程,尽管当我在 Logcat 窗口上打印数据时我的代码工作正常,但是每当我尝试从 asynctask 更新组件时,我的应用程序崩溃并给我一个空点异常。
它给了我以下错误
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);
【问题讨论】:
您正在使用new MainActivity()
创建一个新活动...您需要访问现有的活动。
【参考方案1】:
您需要引用您的活动而不是创建新活动。在这里你可以看到。
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);
【讨论】:
你的代码有效,但它给了我一个警告这个字段在这里泄漏了一个上下文对象 class MyTask extends AsyncTask您收到错误是因为您在未启动 textView 的 onProgressUpdate() 方法中再次创建 mainactivity 类的实例。这就是为什么您在 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");
【讨论】:
以上是关于如何从 android 中的 AsyncTask 获取 UI 参考的主要内容,如果未能解决你的问题,请参考以下文章
如何将变量从 AsyncTask 返回到 Android 中的 Google Map 活动