相關文章:
【線程九講】一、線程狀態切換
【線程九講】二、線程優先級&守護線程
【線程九講】三、線程訪問變量
【線程九講】四、線程異常抓捕
【線程九講】五、線程池
【線程九講】六、鎖與同步
【線程九講】七、阻塞隊列
【線程九講】八、異步計算結果獲取
【線程九講】九、Android異步任務
Handler機制解析
相關 | 用途 | 說明 |
---|---|---|
MessageQueue |
消息隊列容器 | 單鏈表實現 (1) enqueueMessage :添加消息必要時喚醒next (2) next :讀取消息,無消息時阻塞 |
Looper |
消息循環讀取器 | (1)Looper.prepare() :創建MessageQueue (2) Looper.loop() :啓動無限循環調MessageQueue.next() 若返回 null 退出;非null 則調Message#target.dispatchMessage() |
Handler |
消息發送和處理器 | (1)發送:Handler#post Hanlder#sendMessage Looper::myLooper().messageQueue#enqueueMessage ;(2)處理: Hanlder#dispatchMessage Message#callback Hanlder#Callback#handleMessage Handler#handleMessage |
ThreadLocal |
保障Looper互不干擾 | 線程全局變量,原理似HashMap<Thread,T> |
消息處理示例
private volatile Handler mHandler;
private Handler.Callback mCallback = new Handler.Callback() {
@Override
public boolean handleMessage(Message msg) {
Log.e(TAG, "handleMessage: " + Thread.currentThread());
// 執行完畢退出loop循環,銷燬Thread
if(null != Looper.myLooper()){
Looper.myLooper().quitSafely();
}
// Looper#quit 方法會立即退出,quitSafely會在消息處理完畢後退出;
// Looper退出後,Handler#send返回false發送消息失敗;
return true;
}
};
private Runnable mRunnable = new Runnable() {
@Override
public void run() {
Looper.prepare();
// Handler在哪個線程創建就在哪個線程處理
mHandler = new Handler(mCallback);
Looper.loop();
}
};
// =============== 切線程示例 ===============
// 創建處理線程
new Thread(mRunnable, "Thread-0").start();
// 在其他線程發起消息
new Thread(new Runnable() {
@Override
public void run() {
// 切到Thread-0
mHandler.sendEmptyMessage(0x00);
}
},"Thread-1").start();
View單線程模型
爲保證View狀態和操作簡單保障性能,ViewRoomImpl會checkThread
,以保證在主線程操作UI(ActivityThread#main:Looper.prepareMainLooper
)
主線程Looper
AMS中的回調運行在Binder線程池,通過ActivityThread#H
切換到主線程處理各組件生命週期;主線程Looper
初始化過程見ActivityThread::main
執行異步任務的方式
方式 | 使用 | 說明 |
---|---|---|
AsyncTask |
串行啓動:task.execute(param1,param2) 並行啓動: task.executeOnExecutor(params) |
適用輕量級異步任務,便於更新UI 一個AsyncTask對象只能調用execute一次 多個Task在1.6之前和3.0之後默認串行執行 |
HandlerThread |
(1)異步Handler: 創建HanlderThread並 start 用它的 Looper 創建Handler 使用完畢後 HandlerThread#quit (2)IntentService Android在 IntentService#OnCreate 中創建了 HanlderThread 並start 了; |
具有Looper的Thread 注意 start(Looper#loop) 是阻塞的需手動quit |
IntentService |
Context#startService(Intent) |
適用高優先級需報活的耗時任務 能自動退出,比 Thread 更易保活; |
Executor |
execute() ,submit() |
複用Thread 對象, 減少線程建銷成本 |
AsyncTask解析
class AsyncTask<Params,Progress,Result>{
// 主線程,準備執行;
onPreExecute();
// 工作線程池 AsyncTask::SERIAL_EXECUTOR/THREAD_POOL_EXECUTOR
doInBackground(Params...params);
// 主線程,進度已更新;
onProgressUpdate(Progress...progress);
// 主線程,任務完成;
onPostExecute(Result result)
// 主線程,任務取消;
onCancelled();
// 通知進度更新
publishProgress();
// 查詢是否被外部取消
isCancelled();
}
工作流程:
AsyncTask#execute
-> AsyncTask#executeOnExecutor
-> SerialExecutor#execute-> ThreadPoolExecutor#execute
-> FutureTask#run -> WorkerRunnable#call
-> AsyncTask#doInBackground -> AsyncTask#postResult
-> InternalHandler#handleMessage -> AsyncTask#finish
-> AsyncTask#onPostExecute / onCancelled
IntentService解析
注:
- stopSelf(startId): 如果所有任務執行完畢(laststartId==startId?)則退出(當startId=-1立即退出);
- 由於Looper是串行處理消息,所以一個IntentService的多個Intent任務也是串行處理的;