AsyncTask解讀

AsyncTask

概述

  • AsyncTask被設計成助手類,處理HandlerThread,但是它並未形成一般的線程框架。

  • AsyncTasks最好運用在短操作場景(最多幾秒種。)

  • 如果你需要使線程運行保持比較長的時間週期,強烈推薦由java.util.concurrent提供的其他各種API例如Executor,ThreadPoolExecutorFutureTask

  • AsyncTask運行於非主線程,並將結果更新在UI線程。 AsyncTask定義了三個泛型參數Params,Progess,Result,任務執行主要分爲四步onPreExecute,doInBackground,onProgressUpdateonPostExecute

用法

Async必須繼承使用。子類必須重寫doInBackground方法,通常也會重寫onPostExecute

下面是一個例子:

 private class DownloadFilesTask extends AsyncTask<URL, Integer, Long> {
    protected Long doInBackground(URL... urls) {
        int count = urls.length;
        long totalSize = 0;
        for (int i = 0; i < count; i++) {
            totalSize += Downloader.downloadFile(urls[i]);
            publishProgress((int) ((i / (float) count) * 100));
            // Escape early if cancel() is called
            if (isCancelled()) break;
         }
        return totalSize;
    }

    protected void onProgressUpdate(Integer... progress) {
        setProgressPercent(progress[0]);
    }

    protected void onPostExecute(Long result) {
        showDialog("Downloaded " + result + " bytes");
    }
}

子類一旦創建,執行起來非常簡單:

 new DownloadFilesTask().execute(url1, url2, url3);

AsyncTask的三個泛型參數

  1. Params, 任務執行所需要的參數
  2. Progress,後臺任務運行時進度更新的參數
  3. Result,後臺任務結束後的結果參數

並非所有的參數都有作用,如果不需要,刻意簡單的設置爲Void

private class MyTask extends AsyncTask<Void, Void, Void> { ... }

四個步驟

  1. onPreExecute(),在主線程中執行,執行前任務的初始化,可以更新UI。
  2. doInBackground(Params...),在非主線程中執行耗時邏輯。在本步中,可以調用publishProgress(Progress...)更新UI。
  3. onProgressUpdate,在調用publishProgress(Progress...)方法後在主線程中更新UI。
  4. onPostExecute(Result),doInBackground(Params...)執行後在主線程執行。

取消任務

在任何時候,可以通過調用cancel(boolean)取消任務。在調用cancel(boolean) 方法後,調用isCancelled()將返回true,而且在執行完doInBackground(Param...)後將不執行onPostExecute(Object),取而代之的是onCancelled(Object)

Threading rules

  • AsyncTask**必須**在UI線程中加載。在JELLY_BEAN自動完成了此步驟。
  • AsyncTask實例必須在UI線程中創建。
  • execute(Params…)必須在UI線程中調用。
  • 不要人爲調用 onPreExecute(),onPostExecute(Result),doInBackground(Params...),onProgressUpdate(Progress...)
  • 該任務只能執行一次。

Memory observability

AsyncTask確保所有的回調都是同步的,所以以下操作是安全的而不需要顯示同步。
- 在Constructor或者onPreExecute()設置成員變量,然後在doInBackground()中引用相關。
- 在doInBackground()中設置成員變量,然後在onProgressUpdate()onPostExecute()中引用相關。

執行順序

在最初提出,AsyncTask在單後臺線程順序執行。自從DONUT,改爲在一個線程池中多任務並行執行。自從HONEYCOMB,爲了避免由共同應用造成的並行執行錯誤,AsyncTasks在單線程中運行。
如果你確實想要並行執行,你可以調用executeOnExecutor(Java.util.concurrent.Executor,Object[])。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章