上周閑來無事就去某些大公司面試了一下题翻,試試現(xiàn)在android這塊的水!總結(jié)出結(jié)論就是,稍大點的公司問的基礎(chǔ)的東西還是比較的多酬荞,而規(guī)模較小的公司則是更注重模塊功能點的實現(xiàn)!所以呢瞧哟,你未來職業(yè)的發(fā)展得有個大體的規(guī)劃混巧,大公司呢,就多注意一下基礎(chǔ)知識和整體框架的把握勤揩,而規(guī)模稍小的公司則需要你將某些功能塊挖的深一些咧党!這是我個人的感覺,哈哈陨亡!僅供參考傍衡!
進入正題!
AsyncTask已經(jīng)出來太久了负蠕,以至于我們可以很熟悉的用它蛙埂!那它是怎么工作的呢?之前在學(xué)習(xí)android的時候遮糖,看過它的源碼實現(xiàn)绣的!但是實在太久了,差不多都忘光了欲账!今天早上手上的事情做完后無聊屡江,就又走了一遍,突然感覺看別人的源碼比自己擼代碼還要舒服赛不!
我們先從實例化AsyncTask開始逐步了解惩嘉!
OK,我們聊一下這張圖踢故!從WorkerRunnable中我們看到了AsyncTask的一個重要方法doInBackfround()是在這個方法中執(zhí)行的文黎!然后再將WorkerRunnable的引用添加到了FutureTask中執(zhí)行結(jié)果回調(diào)。所以說基本可以確定這是在子線程中的畴椰,當(dāng)然還有一行代碼可以證明:
Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
這行代碼什么意思呢臊诊?
標(biāo)準后臺線程。這讓你的線程低于正常的優(yōu)先級斜脂,這樣會保證用戶界面的響應(yīng)性抓艳。
OK,看到這即可了帚戳!我們不能盲目的鉆到理解代碼的詳細細節(jié)上玷或,不然就出不去了儡首!
AsyncTask實例化完了,我們就改看看他是怎么執(zhí)行的吧偏友!執(zhí)行的話蔬胯,我們通常會調(diào)用它的execute()方法。
嗯位他,知識簡單的執(zhí)行了一個函數(shù)氛濒,并傳入了兩個參數(shù)!sDefaultExecutor和params鹅髓,第二個參數(shù)舞竿,不用說了,就是我們自己傳入的參數(shù)窿冯,第一個呢骗奖?
嗯,它是SerialExecutor的實例化對象醒串,實現(xiàn)了Executor执桌,重要的是下面這行代碼:
final ArrayDeque<Runnable> mTasks = new ArrayDeque<Runnable>();
SerialExecutor通過ArrayDeque控制管理線程池中的Runnable對象,其原理是隊列芜赌,先進先出形式仰挣!
看看它提供的offer方法:
很簡單的翻譯吧!在隊未添加一個Runnable元素较鼓。
再看poll方法:
取出并移除頂部元素
嗯椎木,大概明白了!SerialExecutor是一個線程池博烂,它通過ArrayDeque來控制線程Runnable的執(zhí)行順序香椎!也就是說SerialExecutor是一個排隊的線程池!
接著說executeOnExecutor()禽篱,它將SerialExecutor和params(我們自己設(shè)置的參數(shù))傳過去了畜伐!
哈哈,是不是看到了執(zhí)行流程了躺率?
Pending(等待)-->Running(運行)-->Finished(結(jié)束)
如果非等待狀態(tài)玛界,那就不好意思了!拋出了異常悼吱!
如果是等待狀態(tài)則執(zhí)行:
mStatus更改為RUNNING狀態(tài)慎框;
onPreExecute();執(zhí)行之前預(yù)備狀態(tài)
mWorker.mParams = params;設(shè)置傳過來的參數(shù)
exec.execute(mFuture);開始執(zhí)行
exec則是我們傳過來的SerialExecutor,而mFuture則是我們在實例化的時候生成的子線容器后添!
回過頭再看SerialExecutor
在執(zhí)行 r.run()后笨枯,我們怎么獲得執(zhí)行的結(jié)果呢?
FutureTask執(zhí)行完成后必會調(diào)用
protected void done()
那就會執(zhí)行postResultIfNotInvoked(get());
接著
再接著實例化Handler;
Handler發(fā)送消息進行處理:
這個主意的是馅精,在super(Looper.getMainLooper());執(zhí)行后严嗜,又回到到了主線程!而在執(zhí)行finish方法的時候洲敢,調(diào)用了onPostExecute(result);使得結(jié)果得到了回調(diào)成功漫玄!
OK,執(zhí)行流程大概就是這么個樣子压彭!
總結(jié):
總的來說AsyncTask的內(nèi)部封裝了SERIAL_EXECUTOR(排隊線程池)睦优,THREAD_POOL_EXECUTOR(執(zhí)行線程池),以WorkerRunnable為子線程封裝可回調(diào)控制操作的FutureTask子線程哮塞,以及用于更新界面的一個內(nèi)部InternalHandler刨秆,這么一個結(jié)構(gòu)凳谦,理解起來并不是很難忆畅!關(guān)鍵是人家的這種設(shè)計和一些api的合理使用!
閑話少說尸执,年關(guān)了家凯,估計大伙都蠢蠢欲動!加油吧如失!
每天進步一點點绊诲,時間會讓你成為巨人!