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