我已经在android中编写了AsyncTask
短暂的后台操作已经有一段时间了,并且有一个非常基本的问题。如果我从一个单独的线程而不是主UI线程启动AsyncTask
,我的onPreExecute()
和onPostExecute
方法仍然会在UI线程中调用,或者我从哪个线程调用{ {1}}。我很好奇,因为当我从其他线程启动它时,我无法在AsyncTask
方法中显示弹出窗口。
编辑2
onPreExecute()
这很好。 但是,当我使用以下代码运行应用程序时:
I tried writing this simple activity to try:
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
new Thread(new Runnable() {
@Override
public void run() {
final TestAsyncTask task = new TestAsyncTask();
task.execute();
}
}).start();
}
private class TestAsyncTask extends AsyncTask<Void, Void, Void> {
@Override
protected void onPreExecute() {
super.onPreExecute();
}
@Override
protected Void doInBackground(Void... voids) {
return null;
}
@Override
protected void onPostExecute(Void aVoid) {
super.onPostExecute(aVoid);
Toast.makeText(MainActivity.this, "Yo!", Toast.LENGTH_LONG).show();
}
}
}
失败并出现以下错误:
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
new Thread(new Runnable() {
@Override
public void run() {
final TestAsyncTask task = new TestAsyncTask();
task.execute();
}
}).start();
}
private class TestAsyncTask extends AsyncTask<Void, Void, Void> {
@Override
protected void onPreExecute() {
super.onPreExecute();
Toast.makeText(MainActivity.this, "Yo!", Toast.LENGTH_LONG).show();
}
@Override
protected Void doInBackground(Void... voids) {
return null;
}
}
}
作为堆栈跟踪中的一条线。
答案 0 :(得分:12)
虽然文档说这些回调在主线程中执行 - 但事实并非如此。 onPreExecute()
从executeOnExecutor()
同步运行,即在AsyncTask
开始的主题中运行。
onPostExecute()
始终在主线程中运行。 (它是从finish()
调用的,这发生在使用主线程的looper的Handler
中。)
答案 1 :(得分:4)
您应该在UI线程上运行的AsyncTask onPostExecute()方法中进行UI更新并提醒或弹出显示。 AsyncTask的doinBackground()方法在另一个线程上运行。
答案 2 :(得分:1)
引用官方文档:
flash[:danger]
你可以在https://developer.android.com/reference/android/os/AsyncTask.html#onPostExecute(Result)
找到它后台运行在后台线程上运行,而OnPreExecute和OnPostExecute在主Ui线程上运行。