標籤:android asynctask 源碼 解析
歡迎轉載,請附出處:
http://blog.csdn.net/as02446418/article/details/47684415
注釋都寫在代碼裡了,直接看代碼吧:
/* * Copyright (C) 2008 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */package android.os;import java.util.concurrent.ThreadPoolExecutor;import java.util.concurrent.TimeUnit;import java.util.concurrent.BlockingQueue;import java.util.concurrent.LinkedBlockingQueue;import java.util.concurrent.ThreadFactory;import java.util.concurrent.Callable;import java.util.concurrent.FutureTask;import java.util.concurrent.ExecutionException;import java.util.concurrent.TimeoutException;import java.util.concurrent.CancellationException;import java.util.concurrent.atomic.AtomicInteger;/** * AsyncTask能夠使得操作UI線程更加容易,AsyncTask可以使得在耗時操作得到結果更新UI線程而不依靠Handler等</p> * * An asyntask能夠在後台進行耗時計算操作然後把結果反饋給UI線程,整個操作是非同步,非同步任務總共有三個類屬性Params, Progress and Result, * 和4個步驟, 分別是begin,doInBackground,processProgress and end. * * AsyncTask 至少需要重寫一個方法——doInBackground,最經常用的還有onPostExecute. * 其中三個類屬性 * 1.Params , 當任務開始時需要傳給任務的參數 * 2.Progress , 當後台計算時發布的即時進度 * 3.Result , 後台計算的結果 * 使用AsyncTask需要滿足的條件: * 1.任務必須建立在UI線程中 * 2.使用execute方法必須在UI線程中 * 3.不要顯示地調用onPreExecute,onPostExecute,doInBackground,onProgressUpdate * 4.任務只能exceute一次,不然會拋異常 */public abstract class AsyncTask<Params, Progress, Result> { private static final String LOG_TAG = "AsyncTask"; private static final int CORE_POOL_SIZE = 5; private static final int MAXIMUM_POOL_SIZE = 128; private static final int KEEP_ALIVE = 1; //阻塞隊列 private static final BlockingQueue<Runnable> sWorkQueue = new LinkedBlockingQueue<Runnable>(10); private static final ThreadFactory sThreadFactory = new ThreadFactory() { //原子interger計數變數 private final AtomicInteger mCount = new AtomicInteger(1); //對線程數量進行計數 public Thread newThread(Runnable r) { return new Thread(r, "AsyncTask #" + mCount.getAndIncrement()); } }; //定義了線程池 private static final ThreadPoolExecutor sExecutor = new ThreadPoolExecutor(CORE_POOL_SIZE, MAXIMUM_POOL_SIZE, KEEP_ALIVE, TimeUnit.SECONDS, sWorkQueue, sThreadFactory); private static final int MESSAGE_POST_RESULT = 0x1; private static final int MESSAGE_POST_PROGRESS = 0x2; private static final int MESSAGE_POST_CANCEL = 0x3; //繼承的handler類,內部自己實現的handler private static final InternalHandler sHandler = new InternalHandler(); private final WorkerRunnable<Params, Result> mWorker; //FutureTask容器,存放結果類型 private final FutureTask<Result> mFuture; private volatile Status mStatus = Status.PENDING; /** * 表明任務目前狀態的枚舉,且任務只能處於一種狀態 */ public enum Status { /** * 掛起狀態,還沒開始任務 */ PENDING, /** *運行狀態,表明狀態進行中 */ RUNNING, /** * 結束狀態,表明狀態已完成 */ FINISHED, } /** * 建立AsyncTask,再次聲明:只能在UI線程中建立 */ public AsyncTask() { mWorker = new WorkerRunnable<Params, Result>() { public Result call() throws Exception { Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); return doInBackground(mParams); } }; mFuture = new FutureTask<Result>(mWorker) { @Override protected void done() { Message message; Result result = null; try { result = get(); } catch (InterruptedException e) { android.util.Log.w(LOG_TAG, e); } catch (ExecutionException e) { throw new RuntimeException("An error occured while executing doInBackground()", e.getCause()); } catch (CancellationException e) { message = sHandler.obtainMessage(MESSAGE_POST_CANCEL, new AsyncTaskResult<Result>(AsyncTask.this, (Result[]) null)); message.sendToTarget(); return; } catch (Throwable t) { throw new RuntimeException("An error occured while executing " + "doInBackground()", t); } message = sHandler.obtainMessage(MESSAGE_POST_RESULT, new AsyncTaskResult<Result>(AsyncTask.this, result)); message.sendToTarget(); } }; } /** * 獲得任務目前狀態 * * @return The current status. */ public final Status getStatus() { return mStatus; } /** *這個就是doInBackground的抽象方法了 * * @see #onPreExecute() * @see #onPostExecute * @see #publishProgress */ protected abstract Result doInBackground(Params... params); /** * 在doInBackground之前執行 * * @see #onPostExecute * @see #doInBackground */ protected void onPreExecute() { } /** * 在doInBackground之後執行,如果任務被取消或者拋異常則返回null * * @see #onPreExecute * @see #doInBackground */ @SuppressWarnings({"UnusedDeclaration"}) protected void onPostExecute(Result result) { } /** * 在publishProgress調用後執行,其中參數的values是傳給publishProgress的 * * @see #publishProgress * @see #doInBackground */ @SuppressWarnings({"UnusedDeclaration"}) protected void onProgressUpdate(Progress... values) { } /** * 在cancel()被調用後執行的方法 * * @see #cancel(boolean) * @see #isCancelled() */ protected void onCancelled() { } /** * 如果在正常結束之前取消任務了則返回true,否則為false */ public final boolean isCancelled() { return mFuture.isCancelled(); } /** * 試圖取消執行的任務,途中可能會失敗如果任務已經完成了,或者已經被取消了,或者其他原因, * 如果這個方法在任務啟動之前調用則任務不會啟動,如果在啟動之後調用, * 傳入的參數mayInterruptIfRunning決定了是不是要在任務啟動並執行時候終止任務 * @see #isCancelled() * @see #onCancelled() */ public final boolean cancel(boolean mayInterruptIfRunning) { return mFuture.cancel(mayInterruptIfRunning); } /** * 等待直到結果完成的時候則返回結果 * * @return The computed result. * * @throws CancellationException If the computation was cancelled. * @throws ExecutionException If the computation threw an exception. * @throws InterruptedException If the current thread was interrupted * while waiting. */ public final Result get() throws InterruptedException, ExecutionException { return mFuture.get(); } /** * 等到timeout結束時就檢查結果,不管任務有沒有完成,通常放到耗時任務時 * * @param timeout Time to wait before cancelling the operation. * @param unit The time unit for the timeout. * * @return The computed result. * * @throws CancellationException If the computation was cancelled. * @throws ExecutionException If the computation threw an exception. * @throws InterruptedException If the current thread was interrupted * while waiting. * @throws TimeoutException If the wait timed out. */ public final Result get(long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException { return mFuture.get(timeout, unit); } /** * 返回AsyncTask<Params, Progress, Result>對象,需要在UI線程中執行 * * * @param params The parameters of the task. * * @return This instance of AsyncTask. * * @throws IllegalStateException If {@link #getStatus()} returns either * {@link AsyncTask.Status#RUNNING} or {@link AsyncTask.Status#FINISHED}. */ public final AsyncTask<Params, Progress, Result> execute(Params... params) { if (mStatus != Status.PENDING) { switch (mStatus) { case RUNNING: throw new IllegalStateException("Cannot execute task:" + " the task is already running."); case FINISHED: throw new IllegalStateException("Cannot execute task:" + " the task has already been executed " + "(a task can be executed only once)"); } } mStatus = Status.RUNNING; onPreExecute(); mWorker.mParams = params; sExecutor.execute(mFuture); return this; } /** * 這個方法會被doInBackground調用並表示當前已完成的狀態 * * @see #onProgressUpdate * @see #doInBackground */ protected final void publishProgress(Progress... values) { sHandler.obtainMessage(MESSAGE_POST_PROGRESS, new AsyncTaskResult<Progress>(this, values)).sendToTarget(); } /** * 任務任務時候內部自動調用此方法 */ private void finish(Result result) { if (isCancelled()) result = null; onPostExecute(result); mStatus = Status.FINISHED; } /** * 這個是最重要的內部實現的handler了,根據不同的msg進行分發不同操作 */ private static class InternalHandler extends Handler { @SuppressWarnings({"unchecked", "RawUseOfParameterizedType"}) @Override public void handleMessage(Message msg) { AsyncTaskResult result = (AsyncTaskResult) msg.obj; switch (msg.what) { case MESSAGE_POST_RESULT: // There is only one result result.mTask.finish(result.mData[0]); break; case MESSAGE_POST_PROGRESS: result.mTask.onProgressUpdate(result.mData); break; case MESSAGE_POST_CANCEL: result.mTask.onCancelled(); break; } } } private static abstract class WorkerRunnable<Params, Result> implements Callable<Result> { Params[] mParams; } @SuppressWarnings({"RawUseOfParameterizedType"}) private static class AsyncTaskResult<Data> { final AsyncTask mTask; final Data[] mData; AsyncTaskResult(AsyncTask task, Data... data) { mTask = task; mData = data; } }}
著作權聲明:本文為博主原創文章,未經博主允許不得轉載。
Android之AsyncTask源碼解析