onPreExecute()和onPostExecute()是在UI线程上还是在从中启动AsyncTask的线程上执行的?

时间:2016-08-23 12:52:04

标签: java android multithreading android-asynctask ui-thread

我已经在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;
        }
    }
}

作为堆栈跟踪中的一条线。

3 个答案:

答案 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线程上运行。