Android的AsyncTask原始碼分析
一說到AsyncTask,大家就會說 ,他是系統提供給我的用於執行非同步任務的工具類。比Handler好用只需要重寫方法,每個Asynchronous物件只能執行1次。但是他必須要放在主執行緒裡建立。為什麼呢?這都是為什麼呢?我們就來對這些疑惑一探究竟:
開啟這個類,我喜歡只有除去一些註釋只有250多行:
二話不說,先看他的構造吧:
public AsyncTask() {
mWorker = new WorkerRunnable<Params, Result>() {
public Result call() throws Exception {
Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
return doInBackground(mParams);//呼叫了doInBackground
}
};//構建了一個mWorkà WorkerRunnable是具有prams引數的一個抽象類,實現了Callable介面。
mFuture = new FutureTask<Result>(mWorker) {//用mWorker建立了FutureTask
@Override// FutureTask
(Runnable runnable, V result)
//FutureTask通過一個Runnable/Callable構造,一旦執行完成通過get();返回一個Result
protected void done() {
Message message;
Result result = null;
try {
result = get();//獲得mWork返回的Result
} 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));
// sHandler是自己的Handler:obtainMessage:通過what,obj獲得msg;
//實際呼叫: Message.obtain(this, what, obj);得到1個MSg
message.sendToTarget();//target.send(msg)傳送了一個訊息給自覺封裝好的Handler
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();
}
};
}
這時呼叫了HandleMessage()方法,下面是那個Handler的具體程式碼:
private static class InternalHandler extends Handler {
@SuppressWarnings({"unchecked", "RawUseOfParameterizedType"})
@Override//看到了吧,我們要重寫的幾個方法。他們現在都是空實現。
public void handleMessage(Message msg) {
AsyncTaskResult result = (AsyncTaskResult) msg.obj;//取得訊息裡的Result
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;
}
}
}
這裡涉及到一個AsyncTaskResult result和:
private static class AsyncTaskResult<Data> {//建立分派訊息時,將Result封裝為AsyncTaskResult
final AsyncTask mTask;//封裝1個非同步任務,建立訊息時this
final Data[] mData;//我們建立訊息時mData:為Result
AsyncTaskResult(AsyncTask task, Data... data) {
mTask = task;
mData = data;
}
}
哪為什麼要在Ui執行緒例項化呢,:
因為他的本質還是Handler,Handler物件與當前執行緒關聯,也就說,我們想通過非同步分離UI和後臺處理,當然要在Ui例項化。
為什麼又只能執行1次呢:
我們看,通過程式碼的結構:我們要通過execute執行(為什麼?)來傳遞我們要執行的引數:
他內部定義了一個狀態並初始化為PENGDING:
private volatile Status mStatus = Status.PENDING;
public enum Status {PENDING, RUNNING, 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;//只能在這裡修改1次,這就是執行1次的原因.
onPreExecute();//如果定義了onPreExecute(),則執行,否則空實現;
mWorker.mParams = params;//初始化mWorker的引數
sExecutor.execute(mFuture);//這是執行FutureTask的方式。回到了我上面的講解。
return this;
}
這裡也順便講一下Progress的更新吧:
protected final void publishProgress(Progress... values) {
sHandler.obtainMessage(MESSAGE_POST_PROGRESS,
new AsyncTaskResult<Progress>(this, values)).sendToTarget();
}
這下,你是不是明白呢!
相關文章
- Android 原始碼分析之 AsyncTask 原始碼分析Android原始碼
- Android AsyncTask運作原理和原始碼分析Android原始碼
- Android開發AsyncTask原始碼分析【模板方法模式】Android原始碼模式
- Architecture(1)AsyncTask原始碼分析原始碼
- 原始碼解析Android中AsyncTask的工作原理原始碼Android
- 原始碼分析 —— AsyncTask 完全解析(基於7.0)原始碼
- Android應用AsyncTask處理機制詳解及原始碼分析Android原始碼
- AsyncTask原始碼解析原始碼
- AsyncTask 程式碼分析
- android AsyncTask 的分析與運用Android
- Android AsyncTask完全解析,帶你從原始碼的角度徹底理解Android原始碼
- 【原始碼解析】AsyncTask的用法與規則原始碼
- 【Android原始碼】Fragment 原始碼分析Android原始碼Fragment
- 【Android原始碼】Intent 原始碼分析Android原始碼Intent
- Android 非同步任務知識梳理(1) AsyncTask 原始碼解析Android非同步原始碼
- Android 原始碼分析之 EventBus 的原始碼解析Android原始碼
- 從原始碼角度一步步分析AsyncTask的用法與原理原始碼
- AsyncTask為什麼可以在回撥中修改UI(原始碼分析)UI原始碼
- 【Android原始碼】AlertDialog 原始碼分析Android原始碼
- Android Choreographer 原始碼分析Android原始碼
- Android RecycleView原始碼分析AndroidView原始碼
- Android——Handler原始碼分析Android原始碼
- 【Android原始碼】Handler 機制原始碼分析Android原始碼
- 從原始碼角度談談AsyncTask的使用及其原理原始碼
- Android原始碼分析--CircleImageView 原始碼詳解Android原始碼View
- AsyncTask的分析與運用
- Android中IntentService原始碼分析AndroidIntent原始碼
- Android開源原始碼分析Android原始碼
- 【Android原始碼】LayoutInflater 分析Android原始碼
- Android JiaoZiVideoPlayer原始碼分析AndroidIDE原始碼
- Android SharedPreferences 原始碼分析Android原始碼
- android view layout原始碼分析AndroidView原始碼
- Android 原始碼結構分析Android原始碼
- Android Volley原始碼分析Android原始碼
- Android 原始碼分析之旅3 1 訊息機制原始碼分析Android原始碼
- 【Android原始碼】View的繪製流程分析Android原始碼View
- Android AsyncTask 詳解Android
- android AsyncTask介紹Android