AsyncTask 序列執行和任務的並行執行

AsyncTask 是一個抽象類,不繼承 Thread 類。它有一個抽象方法 doInBackground(Params... params),它被重寫以執行任務。這個方法是從 AsyncTask.call() 呼叫的。

執行人是 java.util.concurrent 包的一部分。

而且,AsyncTask 包含 2 個 Executors

THREAD_POOL_EXECUTOR

它使用工作執行緒並行執行任務。

public static final Executor THREAD_POOL_EXECUTOR = new ThreadPoolExecutor(CORE_POOL_SIZE, MAXIMUM_POOL_SIZE, KEEP_ALIVE, TimeUnit.SECONDS, sPoolWorkQueue, sThreadFactory);

SERIAL_EXECUTOR

它按順序執行任務,即逐個執行。

private static class SerialExecutor implements Executor { }

兩個 Executor 都是靜態的,因此只存在一個 THREAD_POOL_EXECUTOR 和一個 SerialExecutor 物件,但是你可以建立幾個 AsyncTask 物件。

因此,如果你嘗試使用預設的 Executor(SerialExecutor)執行多個後臺任務,則這些任務將按順序排隊並執行。

如果你嘗試使用 THREAD_POOL_EXECUTOR 執行多個後臺任務,那麼它們將並行執行。

例:

public class MainActivity extends Activity {
    private Button bt;
    private int CountTask = 0;
    private static final String TAG = "AsyncTaskExample";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        bt = (Button) findViewById(R.id.button);
        bt.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                BackgroundTask backgroundTask = new BackgroundTask ();
                Integer data[] = { ++CountTask, null, null };

                // Task Executed in thread pool ( 1 )
                backgroundTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, data);

                // Task executed Serially ( 2 )
                // Uncomment the below code and comment the above code of Thread
                // pool Executor and check
                // backgroundTask.execute(data);
                Log.d(TAG, "Task = " + (int) CountTask + " Task Queued");

            }
        });

    }

    private class BackgroundTask extends AsyncTask<Integer, Integer, Integer> {
        int taskNumber;

        @Override
        protected Integer doInBackground(Integer... integers) {
            taskNumber = integers[0];

            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }

            Log.d(TAG, "Task = " + taskNumber + " Task Running in Background");

            publishProgress(taskNumber);
            return null;
        }

        @Override
        protected void onPreExecute() {
            super.onPreExecute();
        }

        @Override
        protected void onPostExecute(Integer aLong) {
            super.onPostExecute(aLong);
        }

        @Override
        protected void onProgressUpdate(Integer... values) {
            super.onProgressUpdate(values);
            Log.d(TAG, "Task = " + (int) values[0]
                    + " Task Execution Completed");
        }
    }
}

多次執行單擊按鈕以啟動任務並檢視結果。

執行緒池中執行的任務(1)

每項任務需要 1000 毫秒才能完成。

在 t = 36s,任務 2,3 和 4 排隊並開始執行,因為它們並行執行。

08-02 19:48:35.815: D/AsyncTaskExample(11693): Task = 1 Task Queued
08-02 19:48:35.815: D/AsyncTaskExample(11693): Task = 1 Task Running in Background
08-02 19:48:**36.025**: D/AsyncTaskExample(11693): Task = 2 Task Queued
08-02 19:48:**36.025**: D/AsyncTaskExample(11693): Task = 2 Task Running in Background
08-02 19:48:**36.165**: D/AsyncTaskExample(11693): Task = 3 Task Queued
08-02 19:48:**36.165**: D/AsyncTaskExample(11693): Task = 3 Task Running in Background
08-02 19:48:**36.325**: D/AsyncTaskExample(11693): Task = 4 Task Queued
08-02 19:48:**36.325**: D/AsyncTaskExample(11693): Task = 4 Task Running in Background
08-02 19:48:**36.815**: D/AsyncTaskExample(11693): Task = 1 Task Execution Completed
08-02 19:48:**36.915**: D/AsyncTaskExample(11693): Task = 5 Task Queued
08-02 19:48:**36.915**: D/AsyncTaskExample(11693): Task = 5 Task Running in Background
08-02 19:48:37.025: D/AsyncTaskExample(11693): Task = 2 Task Execution Completed
08-02 19:48:37.165: D/AsyncTaskExample(11693): Task = 3 Task Execution Completed```

評論 `Task Executed in thread pool`(1)並取消註釋 `Task executed Serially`(2)。

多次執行單擊按鈕以啟動任務並檢視結果。

它正在連續執行任務,因此在當前任務完成執行後啟動每個任務。因此,當任務 1 的執行完成時,只有任務 2 開始在後臺執行。反之亦然。

``` placeholder
08-02 19:42:57.505: D/`AsyncTaskExample(10299)`: Task = 1 Task Queued
08-02 19:42:57.505: D/`AsyncTaskExample(10299)`: Task = 1 Task Running in Background
08-02 19:42:57.675: D/`AsyncTaskExample(10299)`: Task = 2 Task Queued
08-02 19:42:57.835: D/`AsyncTaskExample(10299)`: Task = 3 Task Queued
08-02 19:42:58.005: D/`AsyncTaskExample(10299)`: Task = 4 Task Queued
08-02 19:42:58.155: D/`AsyncTaskExample(10299)`: Task = 5 Task Queued
08-02 19:42:58.505: D/`AsyncTaskExample(10299)`: Task = 1 Task Execution Completed
08-02 19:42:58.505: D/`AsyncTaskExample(10299)`: Task = 2 Task Running in Background
08-02 19:42:58.755: D/`AsyncTaskExample(10299)`: Task = 6 Task Queued
08-02 19:42:59.295: D/`AsyncTaskExample(10299)`: Task = 7 Task Queued
08-02 19:42:59.505: D/`AsyncTaskExample(10299)`: Task = 2 Task Execution Completed
08-02 19:42:59.505: D/`AsyncTaskExample(10299)`: Task = 3 Task Running in Background
08-02 19:43:00.035: D/`AsyncTaskExample(10299)`: Task = 8 Task Queued
08-02 19:43:00.505: D/`AsyncTaskExample(10299)`: Task = 3 Task Execution Completed
08-02 19:43:**00.505**: D/`AsyncTaskExample(10299)`: Task = 4 Task Running in Background
08-02 19:43:**01.505**: D/`AsyncTaskExample(10299)`: Task = 4 Task Execution Completed
08-02 19:43:**01.515**: D/`AsyncTaskExample(10299)`: Task = 5 Task Running in Background
08-02 19:43:**02.515**: D/`AsyncTaskExample(10299)`: Task = 5 Task Execution Completed
08-02 19:43:**02.515**: D/`AsyncTaskExample(10299)`: Task = 6 Task Running in Background
08-02 19:43:**03.515**: D/`AsyncTaskExample(10299)`: Task = 7 Task Running in Background
08-02 19:43:**03.515**: D/`AsyncTaskExample(10299)`: Task = 6 Task Execution Completed
08-02 19:43:04.515: D/`AsyncTaskExample(10299)`: Task = 8 Task Running in Background
08-02 19:43:**04.515**: D/`AsyncTaskExample(10299)`: Task = 7 Task Execution Completed