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原始碼
- AsyncTask原始碼解析原始碼
- AsyncTask 程式碼分析
- Android 原始碼分析之 EventBus 的原始碼解析Android原始碼
- 【原始碼解析】AsyncTask的用法與規則原始碼
- Android Choreographer 原始碼分析Android原始碼
- Android AsyncTask 詳解Android
- Android中IntentService原始碼分析AndroidIntent原始碼
- android IO Prefetch原始碼分析Android原始碼
- Android開源原始碼分析Android原始碼
- 從原始碼角度談談AsyncTask的使用及其原理原始碼
- Android原始碼分析–ArrayMap優化Android原始碼優化
- Android Sensor原始碼分析總結Android原始碼
- Android 8.0 原始碼分析 (八) ActivityManagerServiceAndroid原始碼
- Android Jetpack系列——ViewModel原始碼分析AndroidJetpackView原始碼
- Android 系統原始碼-1:Android 系統啟動流程原始碼分析Android原始碼
- React Native 0.55.4 Android 原始碼分析(Java層原始碼解析)React NativeAndroid原始碼Java
- Android Activity啟動流程原始碼分析Android原始碼
- Android系統原始碼分析之-ContentProviderAndroid原始碼IDE
- Android 原始碼分析(二)handler 機制Android原始碼
- Android系統原始碼分析-事件收集Android原始碼事件
- Android View 事件分發原始碼分析AndroidView事件原始碼
- Android 7 原始碼分析系列導讀Android原始碼
- Android原始碼分析:Activity啟動流程Android原始碼
- Android View繪製原始碼分析 MeasureAndroidView原始碼
- Android原始碼分析(LayoutInflater.from(this).inflate(resId,null);原始碼解析)Android原始碼Null
- Android的AsyncTask非同步任務淺析Android非同步
- Android 8.0 原始碼分析 (十) WindowManagerService 的視窗管理Android原始碼
- Android中非同步任務(AsyncTask)Android非同步
- Android Hook框架Xposed原理與原始碼分析AndroidHook框架原始碼
- Android原始碼分析之備忘錄模式Android原始碼模式
- Android 外掛化框架 DynamicLoadApk 原始碼分析Android框架APK原始碼
- Android原始碼分析之View繪製流程Android原始碼View
- Android 8.0 原始碼分析 (六) BroadcastReceiver 啟動Android原始碼AST
- Android 8.0 原始碼分析 (五) Service 啟動Android原始碼
- Android 8.0 原始碼分析 (四) Activity 啟動Android原始碼
- Android系統原始碼分析-Broadcast傳送Android原始碼AST
- Flutter之Android層面原始碼分析(一)FlutterAndroid原始碼
- Flutter Android 端 Activity/Fragment 流程原始碼分析FlutterAndroidFragment原始碼