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

Swa*_*nil 8 java multithreading android ui-thread android-asynctask

我一直AsyncTask在为android的短时间背景操作编写很长一段时间,并且有一个非常基本的问题.如果我一开始AsyncTask从一个单独的线程,而不是在主UI线程,将我onPreExecute()onPostExecute方法被称为静止在UI线程或从我开始的线程AsyncTask.我很好奇,因为onPreExecute()当我从其他线程启动它时,我无法在方法中显示弹出窗口.

编辑2

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();
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

这很好.但是当我使用以下代码运行应用程序时:

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;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

它失败并出现以下错误:

Caused by: java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()
Run Code Online (Sandbox Code Playgroud)

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

Ser*_*gio 12

虽然docs说这些回调在主线程中执行 - 但事实并非如此.onPreExecute()executeOnExecutor()启动的线程中的ie 同步运行AsyncTask.

onPostExecute()总是在主线程中运行.(它是从中调用的finish(),这发生在Handler使用主线程的looper的内部).