簡單說說AsyncTask

CarC69 8年前發布 | 4K 次閱讀 AsyncTask Android開發 移動開發

AsyncTask簡單來說就是Android自身提供的一個簡化 后臺讀取數據,主線程更新UI 的幫助類,避免了開發者自身去實現Thread和Handler的邏輯。

AsyncTask enables proper and easy use of the UI thread. This class allows to perform background operations and publish results on the UI thread without having to manipulate threads and/or handlers.

AsyncTask的基本使用就是4個回調方法

onPreExecute()

doInBackground(Params... params)

onProgressUpdate(Progress… value)

onPostExecute(Result result)

AsyncTask內部使用了一個SerialExecutor的執行器來執行任務,從名字就可以看出該執行器是串行執行任的,如果是通過以下代碼來開啟多個AsyncTask的執行,那么Tasks之間并不是并行的關系,而是一個完成之后再繼續下一個的串行關系。

asyncTask.execute(params);

SerialExecutor的實現

private static class SerialExecutor implements Executor {
        final ArrayDeque<Runnable> mTasks = new ArrayDeque<Runnable>();
        Runnable mActive;

        public synchronized void execute(final Runnable r) {
            mTasks.offer(new Runnable() {
                public void run() {
                    try {
                        r.run();
                    } finally {
                        scheduleNext();
                    }
                }
            });
            if (mActive == null) {
                scheduleNext();
            }
        }

        protected synchronized void scheduleNext() {
            if ((mActive = mTasks.poll()) != null) {
                THREAD_POOL_EXECUTOR.execute(mActive);
            }
        }
    }

可以看出SerialExecutor每次的execute是先將需要執行任務封裝進一個添加了任務調度邏輯的任務中,并將該任務添加至隊列中,最后再根據當前有無正在執行的任務決定是否開啟新一輪的串行任務執行。

如果我們想要多個AsyncTask并行執行應該怎么辦呢?

public final AsyncTask<Params, Progress, Result> executeOnExecutor(Executor exec,
            Params... params)

這是AsyncTask提供的另一個開啟任務的方法,該方法是可以指定Executor的,AsyncTask除了SerialExecutor還提供了另一個執行器THREAD_POOL_EXECUTOR,一個 支持最多128個待喚醒任務的并行Executor。

使用一下代碼就可以讓多個任務并行執行

asyncTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR,params);

當然如果AsyncTask提供的執行器不能滿足需求,開發者還可以定義自己的Executor。

另外AsyncTask有一個被隱藏的設置執行器的方法,作為內部方法使用

/** @hide */
    public static void setDefaultExecutor(Executor exec) {
        sDefaultExecutor = exec;
    }

畢竟如果在多個AsyncTask執行期間調用該方法來切換默認執行器的話容易造成Task的調用混亂。

之前說到AsyncTask的的基本使用就是4個步驟,并且4步是執行在不同的線程的,那這是如何實現的呢?

簡單描述下就是AsyncTask是通過WorkRunnable, FutureTask, Handler走完自己的基本生命周期的。在execute(params..)或者executeOnExecutor(executor, params...)之后onPreExecute()就會被調用,緊接著params會傳遞到一個WorkRunnable實例中,該實例和FutureTask的實例一樣都是在AsyncTask的構造函數中實例化和初始化的,然后是將包含了該WorkRunnable實例的FutureTask實例加入執行器中等待執行,當該任務被執行到時,WorkRunnable會負責執行doInBackground(params)然后將返回的結果通過postResult(result)發送,其實現就是通過Handler發送一條狀態為執行完成的消息,Handler處理消息則會根據當前AsyncTask是否已經被取消調用onCancelled(result)或者onPostExecute(result),這樣一個任務就執行完成了。至于onProgressUpdate(progress)則是在調用publishProgress(progress)后通過Handler發送狀態為更新的消息。

最后關于AsyncTask的使用有一點需要注意的是它的生命周期比較難確定,即使是調用了cancel(interrupt = true)方法也不能保證AsyncTask會直接掛掉,所以如果是在Activity等上下文中使用AsyncTask的話就需要注意內存泄漏問題,尤其是由于屏幕旋轉造成的Activity生命周期變化問題,最好不要使用匿名內部類這樣的實例化方式。

以上基于SDK-24源碼,如有問題請指正。

 

來自:http://www.jianshu.com/p/e641d83d5e70

 

 本文由用戶 CarC69 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!