總結:
asynctak 封裝了 thread 和 handler,所以可以在子執行緒中執行任務,在主線程中更新 ui
如果應用和主線程沒有互動,則應該使用 thread,而不是 asynctask
1.1 asynctask 的使用限制
1.asynctask 必須在主線程中載入,保證了 handler 採用主線程的 looper 構建
2.asynctask 的物件必須在主線程中建立,保證了 handler 操作 ui 的執行緒是主線程
3. execute 方法必須在 執行緒 ui 呼叫,和上一條是乙個意思
4. 乙個 asynctask 物件只能呼叫一次 execute() 方法,否則會拋異常
從 execute() 開始:
@mainthread
public final asynctask
execute
(params... params)
executeonexecutor():// asynctask 的初始狀態 mstatus = pending
private volatile status mstatus = status.
pending
;@mainthread
public final asynctask
executeonexecutor
(executor exec, params... params)
}// 當前狀態為 pending,設定為 running
mstatus = status.
running
;onpreexecute()
; mworker.mparams = params;
// 關鍵一:exec.execute(mfuture);
exec.
execute
(mfuture)
;return
this
;}
關鍵一:exec.execute(mfuture);
exec 在 asynctask#execute() 方法中被賦值為 sdefaultexecutor
private
static volatile executor sdefaultexecutor =
serial_executor
;public
static final executor serial_executor
=new
serialexecutor()
;private
static
class
serialexecutor
implements
executor
finally}}
);if(mactive ==
null)}
protected synchronized void
schedulenext()
}}
從上面的**中,sdefaultexecutor 實際上是乙個序列的執行緒池,asynctask 預設使用的就是該執行緒池,乙個程序中所有的非同步任務全部在這個執行緒池中排隊執行
關鍵二:r.run();
r 指的是 mfuture,是乙個 futuretask 物件,是乙個併發類,充當了 runnable 的作用
public
asynctask()
catch
(throwable tr)
finally
return result;}}
;// 建立 futuretask 物件,傳入了上面自定義的 workerrunnable 物件
mfuture =
newfuturetask
(mworker)
catch
(interruptedexception e)
catch
(executionexception e)
catch
(cancellationexception e)}}
;}// 自定義的 workerrunnable 實現了 callable 介面
private
static abstract class
workerrunnable
implements
callable
r.run() -> futuretask#run() -> callable#call() -> workerrunnable#call()
callback 就是通過 futuretask 構造方法傳入的自定義 workerrunnable,其實現了 callable 介面,所以最終呼叫的是 workerrunnable#call(),執行流程如圖所示:
由上圖可知,workerrunnable#call() 最終將執行結果 result 傳遞給了 postresult() 方法
關鍵三:postresult(result);
private result postresult
(result result)
傳送的 message_post_result 訊息通過 asynctask 中自定義的靜態內部類 internalhandler 處理
private
static
class
internalhandler
extends
handler
@suppresswarnings()
@override
public
void
handlemessage
(message msg)
}}
result 是 asynctaskresult 物件
關鍵四:result.mtask.finish(result.mdata[0])
@suppresswarnings()
private
static
class
asynctaskresult
}
result.mtask.finish(result.mdata[0]) 最終其實呼叫的是 asynctask#finish() 方法
private
void
finish
(result result)
else
mstatus = status.
finished
;}
在 android 1.6 之前,asynctask 是序列執行任務
在 android 1.6 之後,3.0 之前,asynctask 採用執行緒池並行執行任務
從 android 3.0 開始,為了避免併發帶來的錯誤,asynctask 又採用乙個執行緒來序列執行任務,但是提供了 executeonexecutor(executor exec, params… params) 來並行執行任務
LeetCode第三十題 Python實現
title leetcode no.30 categories tags 給定乙個字串 s 和一些長度相同的單詞 words。找出 s 中恰好可以由 words 中所有單詞串聯形成的子串的起始位置。注意子串要與 words 中的單詞完全匹配,中間不能有其他字元,但不需要考慮 words 中單詞串聯的...
python爬蟲學習第三十天
今天的內容 維基百科六度分割 終結篇 還記得之前,我們建立了收集從凱文 貝肯開始的維基詞條鏈結的爬蟲,最後儲存在資料庫 裡。為什麼這裡又把這個遊戲搬出來?因為它體現了一種從乙個頁面指向另乙個頁面的鏈 接路徑選擇問題 即找出 和 org wiki eric idle 鏈結路徑 這和從上面的馬爾可夫鏈裡...
python全棧第三十天 git
目錄 git 本地 安裝建立本地倉庫 設定倉庫資訊 檢視檔案狀態記錄 新增修改到工作區 從工作區刪除 從工作區恢復 提交到快取區 檢視快取區的歷史記錄 儲存更改記錄 遠端 轉殖本地推送到遠端 標籤 分支檢視分支 建立分支 切換分支 合併分支 刪除分支 推送分支 git commit m 注釋 git...