### **概述**
Android應用程序與傳統的PC應用程序一樣,都是消息驅動的。也就是說,在Android應用程序主線程中,所有函數都是在一個消息循環中執行的。Android應用程序其它線程,也可以像主線程一樣,擁有消息循環。Android應用程序主線程是一個特殊的線程,因為它同時也是UI線程以及觸摸屏、鍵盤等輸入事件處理線程。主線程對消息循環很敏感,一旦發生阻塞,就會影響UI的流暢度,甚至發生ANR問題。
主要講Android應用程序線程消息循環原理,主要涉及到Handler和Looper兩個類,以及根據消息循環的不同使用場景,總結出三種線程使用模型。掌握Android應用程序消息處理機制,有助于我們熟練地使用同步和異步編程,提高程序的運行性能。
* 線程與消息的關系
* 線程的消息隊列創建
* 線程的消息循環
* 線程的消息發送
* 線程的消息處理
* 消息在異步任務的應用
#### **線程與消息的關系**
**Android應用程序有兩種類型的線程**
* 帶有消息隊列,用來執行循環性任務
* 有消息時就處理
* 沒有消息時就睡眠
* 例子:主線程、android.os.HandlerThread
* 沒有消息隊列,用來執行一次性任務
* 任務一旦執行完成便退出
* 例子:java.lang.Thread
**帶有消息隊列的線程四要素**
* Message(消息)
* MessageQueue(消息隊列)
* Looper(消息循環)
* Handler(消息發送和處理)
**Message、 MessageQueue、 Looper和Handler的交互過程**

#### **線程的消息隊列創建**
**MessageQueue與Looper的關系**

**例1:ServerThread**

**例2:ActivityThread**

**Looper.prepare/prepareMainLooper**

**new Looper – 創建Java層的Looper**

**new MessageQueue**

**nativeInit**

**new NativeMessageQueue**

**new Looper – 創建C++層的Looper**

**pipe**
* 一種進程/線程間通信機制
* 包含一個寫端文件描述符和一個讀端文件描述符
* Looper通過讀端文件描述符等待新消息的到來
* Handler通過寫端文件描述符通知Looper新消息的到來

**epoll**
* 一種I/O多路復用技術,select/poll加強版
* epoll_create:創建一個epoll句柄
* epoll_ctl:設置要監控的文件描述符
* epoll_wait:等待監控的文件描述符發生IO事件
* Looper利用epoll來監控消息隊列是否有新的消息,也就是監控消息管道的讀端文件描述符
**為什么要用epoll**
Looper除了監控消息管道之外,還需要監控其它文件描述符,例如,用來接收鍵盤/觸摸屏事件的文件描述符
#### **線程的消息循環**
**例1:ServerThread**

**例2:ActivityThread**

**Looper.loop – Java層的Looper**

**MessageQueue.next**

**nativePollOnce**

**NativeMessageQueue.pollOnce**

**Looper.pollOnce – C++層的Looper**

**Looper.pollInner**

**Looper.awoken**

#### **線程的消息發送**
**常用的消息發送接口**
* Handler.sendMessage
帶一個Message參數,用來描述消息的內容
* Handler.post
帶一個Runnable參數,會被轉換為一個Message參數
**Message**

**Handler.sendMessage/post**

**Handler.sendMessageDelayed**

**Handler.sendMessageAtTime**

**Handler.enqueueMessage**

**MessageQueue.enqueueMessage**

**備注**:
mBlocked:Indicates whether next() is blocked waiting in pollOnce() with a non-zero timeout.
**nativeWake**

**NativeMessageQueue.wake**

**Looper.wake**

**回顧消息循環過程**

**Handler.dispatchMessage**

#### **消息在異步任務的應用**
**在主線程為什么要用異步任務?**
* 主線程任務繁重
* 執行組件生命周期函數
* 執行業務邏輯
* 執行用戶交互
* 執行UI渲染
* 主線程處理某一個消息時間過長時會產生ANR
* Service生命周期函數 – 20s
* Broadcast Receiver接收前臺優先級廣播函數 –10s
* Broadcast Receiver接收后臺優先級廣播函數 – 60s
* 影響輸入事件處理的函數 – 5s
* 影響進程啟動的函數 – 10s
* 影響Activity切換的函數– 2s
**備注**:
一個進程如果正在接收一個前臺優先級廣播,那么它所在的進程調度組就為Process.THREAD_GROUP_DEFAULT ,如果是正在接收后臺優先級廣播,那么它所在的進程調度組就為Process.THREAD_GROUP_BG_NONINTERACTIVE。發送廣播時,通過Intent.FLAG_RECEIVER_FOREGROUND標志來指定是前臺優先級還是后臺優先級
**基于消息的異步任務接口**
* android.os.HandlerThread
適合用來處于不需要更新UI的后臺任務
* android.os.AyncTask
適合用來處于需要更新UI的后臺任務
**android.os.HandlerThread**

**啟動HandlerThread**
~~~
HandlerThread handlerThread = new HandlerThread("Handler Thread");
handlerThread.start();
~~~
**向HandlerThread分配任務**

~~~
ThreadTask threadTask = new ThreadTask();
Handler handler = new Handler(handlerThread.getLooper());
handler.post(threadTask);
~~~
**退出HandlerThread**
~~~
handlerThread.quit();
~~~

**android.os.AyncTask**
* 在進程內維護一個線程池來執行任務
* 任務在開始執行、執行過程以及結束執行時均可以與主線程進行交互
* 任務是通過一個Handler向主線程發送消息以達到交互的目的
**例子**

**AysnTask的相關成員變量定義**

**用來向主線程發送消息的InternalHandler**

**任務執行過程或者結果數據--AsyncTaskResult**

**創建任務**

**執行任務**


**觸發AsyncTask.doInBackground在工作線程中被調用**
**更新任務進度**


**MESSAGE_POST_PROGRESS通過sHandler發送到主線程的消息隊列**
**觸發AsyncTask.onProgressUpdate在主線程中被**
**任務結束時,MESSAGE_POST_RESULT通過sHandler發送到主線程的消息隊列,觸發AsyncTask.finish在主線程中被調用**



**進一步觸發AsyncTask.onPostExecute在主線程中被調用**
**任務中途取消時,MESSAGE_POST_CANCEL通過sHandler發送到主線程的消息隊列,觸發AsyncTask.onCancel在主線程中被調用**



- 前言
- Android組件設計思想
- Android源代碼開發和調試環境搭建
- Android源代碼下載和編譯
- Android源代碼情景分析法
- Android源代碼調試分析法
- 手把手教你為手機編譯ROM
- 在Ubuntu上下載、編譯和安裝Android最新源代碼
- 在Ubuntu上下載、編譯和安裝Android最新內核源代碼(Linux Kernel)
- 如何單獨編譯Android源代碼中的模塊
- 在Ubuntu上為Android系統編寫Linux內核驅動程序
- 在Ubuntu上為Android系統內置C可執行程序測試Linux內核驅動程序
- 在Ubuntu上為Android增加硬件抽象層(HAL)模塊訪問Linux內核驅動程序
- 在Ubuntu為Android硬件抽象層(HAL)模塊編寫JNI方法提供Java訪問硬件服務接口
- 在Ubuntu上為Android系統的Application Frameworks層增加硬件訪問服務
- 在Ubuntu上為Android系統內置Java應用程序測試Application Frameworks層的硬件服務
- Android源代碼倉庫及其管理工具Repo分析
- Android編譯系統簡要介紹和學習計劃
- Android編譯系統環境初始化過程分析
- Android源代碼編譯命令m/mm/mmm/make分析
- Android系統鏡像文件的打包過程分析
- 從CM刷機過程和原理分析Android系統結構
- Android系統架構概述
- Android系統整體架構
- android專用驅動
- Android硬件抽象層HAL
- Android應用程序組件
- Android應用程序框架
- Android用戶界面架構
- Android虛擬機之Dalvik虛擬機
- Android硬件抽象層
- Android硬件抽象層(HAL)概要介紹和學習計劃
- Android專用驅動
- Android Logger驅動系統
- Android日志系統驅動程序Logger源代碼分析
- Android應用程序框架層和系統運行庫層日志系統源代碼分析
- Android日志系統Logcat源代碼簡要分析
- Android Binder驅動系統
- Android進程間通信(IPC)機制Binder簡要介紹和學習計劃
- 淺談Service Manager成為Android進程間通信(IPC)機制Binder守護進程之路
- 淺談Android系統進程間通信(IPC)機制Binder中的Server和Client獲得Service Manager接口之路
- Android系統進程間通信(IPC)機制Binder中的Server啟動過程源代碼分析
- Android系統進程間通信(IPC)機制Binder中的Client獲得Server遠程接口過程源代碼分析
- Android系統進程間通信Binder機制在應用程序框架層的Java接口源代碼分析
- Android Ashmem驅動系統
- Android系統匿名共享內存Ashmem(Anonymous Shared Memory)簡要介紹和學習計劃
- Android系統匿名共享內存Ashmem(Anonymous Shared Memory)驅動程序源代碼分析
- Android系統匿名共享內存Ashmem(Anonymous Shared Memory)在進程間共享的原理分析
- Android系統匿名共享內存(Anonymous Shared Memory)C++調用接口分析
- Android應用程序進程管理
- Android應用程序進程啟動過程的源代碼分析
- Android系統進程Zygote啟動過程的源代碼分析
- Android系統默認Home應用程序(Launcher)的啟動過程源代碼分析
- Android應用程序消息機制
- Android應用程序消息處理機制(Looper、Handler)分析
- Android應用程序線程消息循環模型分析
- Android應用程序輸入事件分發和處理機制
- Android應用程序鍵盤(Keyboard)消息處理機制分析
- Android應用程序UI架構
- Android系統的開機畫面顯示過程分析
- Android幀緩沖區(Frame Buffer)硬件抽象層(HAL)模塊Gralloc的實現原理分析
- SurfaceFlinger
- Android系統Surface機制的SurfaceFlinger服務
- SurfaceFlinger服務簡要介紹和學習計劃
- 啟動過程分析
- 對幀緩沖區(Frame Buffer)的管理分析
- 線程模型分析
- 渲染應用程序UI的過程分析
- Android應用程序與SurfaceFlinger服務的關系
- 概述和學習計劃
- 連接過程分析
- 共享UI元數據(SharedClient)的創建過程分析
- 創建Surface的過程分析
- 渲染Surface的過程分析
- Android應用程序窗口(Activity)
- 實現框架簡要介紹和學習計劃
- 運行上下文環境(Context)的創建過程分析
- 窗口對象(Window)的創建過程分析
- 視圖對象(View)的創建過程分析
- 與WindowManagerService服務的連接過程分析
- 繪圖表面(Surface)的創建過程分析
- 測量(Measure)、布局(Layout)和繪制(Draw)過程分析
- WindowManagerService
- WindowManagerService的簡要介紹和學習計劃
- 計算Activity窗口大小的過程分析
- 對窗口的組織方式分析
- 對輸入法窗口(Input Method Window)的管理分析
- 對壁紙窗口(Wallpaper Window)的管理分析
- 計算窗口Z軸位置的過程分析
- 顯示Activity組件的啟動窗口(Starting Window)的過程分析
- 切換Activity窗口(App Transition)的過程分析
- 顯示窗口動畫的原理分析
- Android控件TextView的實現原理分析
- Android視圖SurfaceView的實現原理分析
- Android應用程序UI硬件加速渲染
- 簡要介紹和學習計劃
- 環境初始化過程分析
- 預加載資源地圖集服務(Asset Atlas Service)分析
- Display List構建過程分析
- Display List渲染過程分析
- 動畫執行過程分析
- Android應用程序資源管理框架
- Android資源管理框架(Asset Manager)
- Asset Manager 簡要介紹和學習計劃
- 編譯和打包過程分析
- Asset Manager的創建過程分析
- 查找過程分析
- Dalvik虛擬機和ART虛擬機
- Dalvik虛擬機
- Dalvik虛擬機簡要介紹和學習計劃
- Dalvik虛擬機的啟動過程分析
- Dalvik虛擬機的運行過程分析
- Dalvik虛擬機JNI方法的注冊過程分析
- Dalvik虛擬機進程和線程的創建過程分析
- Dalvik虛擬機垃圾收集機制簡要介紹和學習計劃
- Dalvik虛擬機Java堆創建過程分析
- Dalvik虛擬機為新創建對象分配內存的過程分析
- Dalvik虛擬機垃圾收集(GC)過程分析
- ART虛擬機
- Android ART運行時無縫替換Dalvik虛擬機的過程分析
- Android運行時ART簡要介紹和學習計劃
- Android運行時ART加載OAT文件的過程分析
- Android運行時ART加載類和方法的過程分析
- Android運行時ART執行類方法的過程分析
- ART運行時垃圾收集機制簡要介紹和學習計劃
- ART運行時Java堆創建過程分析
- ART運行時為新創建對象分配內存的過程分析
- ART運行時垃圾收集(GC)過程分析
- ART運行時Compacting GC簡要介紹和學習計劃
- ART運行時Compacting GC堆創建過程分析
- ART運行時Compacting GC為新創建對象分配內存的過程分析
- ART運行時Semi-Space(SS)和Generational Semi-Space(GSS)GC執行過程分析
- ART運行時Mark-Compact( MC)GC執行過程分析
- ART運行時Foreground GC和Background GC切換過程分析
- Android安全機制
- SEAndroid安全機制簡要介紹和學習計劃
- SEAndroid安全機制框架分析
- SEAndroid安全機制中的文件安全上下文關聯分析
- SEAndroid安全機制中的進程安全上下文關聯分析
- SEAndroid安全機制對Android屬性訪問的保護分析
- SEAndroid安全機制對Binder IPC的保護分析
- 從NDK在非Root手機上的調試原理探討Android的安全機制
- APK防反編譯
- Android視頻硬解穩定性問題探討和處理
- Android系統的智能指針(輕量級指針、強指針和弱指針)的實現原理分析
- Android應用程序安裝過程源代碼分析
- Android應用程序啟動過程源代碼分析
- 四大組件源代碼分析
- Activity
- Android應用程序的Activity啟動過程簡要介紹和學習計劃
- Android應用程序內部啟動Activity過程(startActivity)的源代碼分析
- 解開Android應用程序組件Activity的"singleTask"之謎
- Android應用程序在新的進程中啟動新的Activity的方法和過程分析
- Service
- Android應用程序綁定服務(bindService)的過程源代碼分析
- ContentProvider
- Android應用程序組件Content Provider簡要介紹和學習計劃
- Android應用程序組件Content Provider應用實例
- Android應用程序組件Content Provider的啟動過程源代碼分析
- Android應用程序組件Content Provider在應用程序之間共享數據的原理分析
- Android應用程序組件Content Provider的共享數據更新通知機制分析
- BroadcastReceiver
- Android系統中的廣播(Broadcast)機制簡要介紹和學習計劃
- Android應用程序注冊廣播接收器(registerReceiver)的過程分析
- Android應用程序發送廣播(sendBroadcast)的過程分析