Android AsyncTask原始碼分析

2021-09-19 09:09:53 字數 3569 閱讀 3123

android中只能在主線程中進行ui操作,如果是其它子執行緒,需要借助非同步訊息處理機制handler。除此之外,還有個非常方便的asynctask類,這個類內部封裝了handler和執行緒池。本文先簡要介紹asynctask的用法,然後分析具體實現。

asynctask是乙個抽象類,我們需要建立子類去繼承它,並且重寫一些方法。asynctask接受三個泛型引數:

除了指定泛型引數,還需要根據需要重寫一些方法,常用的如下:

下面分析這個類的實現,主要有執行緒池以及handler兩部分。

當執行乙個asynctask的時候呼叫的是execute()方法,就從這個開始看:

public final asynctaskexecute(params... params)

public final asynctaskexecuteonexecutor(executor exec,

params... params)

} mstatus = status.running;

//先執行 onpreexecute

onpreexecute();

mworker.mparams = params;

exec.execute(mfuture);

return this;

}

execute方法會呼叫executeonexecutor。在這個方法中先檢查任務是否已經執行或者執行結束,然後把任務標記為running。最開始執行的是onpreexecute,接著把引數賦值給mworker物件。這個mworker是乙個callable物件,最終被包裝為futuretask,**如下:

private static abstract class workerrunnableimplements callable 

mworker = new workerrunnable()

};mfuture = new futuretask(mworker) catch (interruptedexception e) catch (executionexception e) catch (cancellationexception e)

} };

從上面的**可以看出,在mworker物件中的call()方法會呼叫doinbackground,返回值交給postresult方法,這個方法通過handler傳送訊息,這一點稍後再詳細分析。

mworker物件被封裝成futuretask之後交由執行緒池執行,從execute方法可以看出,使用的是sdefaultexecutor,它的值預設為serial_executor,也就是序列執行器,實現如下:

private static class serialexecutor implements executor  finally   

} });

if (mactive == null)

} protected synchronized void schedulenext()

} }public static final executor thread_pool_executor

= new threadpoolexecutor(core_pool_size, maximum_pool_size, keep_alive,

timeunit.seconds, spoolworkqueue, sthreadfactory);

在上面的**中,如果有任務執行,那麼serialexecutorexecute方法會被呼叫,它的邏輯是把runnable物件加入arraydeque佇列中,然後判斷mactivie是否為空。第一次執行時mactive當然為空,所以執行schedulenext,其實就是取出任務佇列中的第乙個任務交給執行緒池(thread_pool_executor)執行。加入mtask佇列的runnable物件的run方法裡最終一定會呼叫schedulenext,那麼又會從任務佇列中取出隊頭任務執行。這樣便實現了單執行緒順序執行任務,所以在asynctask預設啟用的是單執行緒執行,只有上乙個任務執行後才會執行下乙個任務。如果想要啟用多執行緒執行任務,可以直接呼叫executeonexecutor(executor exec, params... params),這裡的executor引數可以使用asynctask自帶的thread_pool_executor,也可以自己定義。

asynctask內部用handler傳遞訊息,它的實現如下:

private static class internalhandler extends handler )  

@override

public void handlemessage(message msg)

} }

如果訊息型別是任務執行後的返回值(message_post_result)將呼叫finish()方法:

private void finish(result result)  else   

mstatus = status.finished;

}

從上面可以知道,如果任務取消了,將呼叫oncancelled,否則呼叫onpostexecute,所以乙個asynctask任務如果取消了,那麼onpostexecute將不會得到執行。

如果訊息型別是執行進度(message_post_progress)將呼叫onprogressupdate,這個方法預設是空方法,我們可以根據自己的需要重寫。

asynctask的主要邏輯就如上面所分析的,總結幾個需要注意的地方:

android原始碼分析—帶你認識不一樣的asynctask

android asynctask完全解析,帶你從原始碼的角度徹底理解

Cartographer原始碼篇 原始碼分析 1

在安裝編譯cartographer 1.0.0的時候,我們可以看到 主要包括cartorgarpher ros cartographer ceres sover三個部分。其中,ceres solver用於非線性優化,求解最小二乘問題 cartographer ros為ros平台的封裝,獲取感測器資料...

AbstractListView原始碼分析3

normal list that does not indicate choices public static final int choice mode none 0 the list allows up to one choice public static final int choice ...

SpringCloud Nacos原始碼分析

開啟 為什麼這樣修改引數,那就要檢視原始碼了!systemutils類 the system property name of standalone mode public static final string standalone mode property name nacos.standal...