AsyncTask 序列執行和任務的並行執行
AsyncTask 是一個抽象類,不繼承 Thread
類。它有一個抽象方法 doInBackground(Params... params)
,它被重寫以執行任務。這個方法是從 AsyncTask.call()
呼叫的。
執行人是 java.util.concurrent
包的一部分。
而且,AsyncTask 包含 2 個 Executor
s
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