由於Android采用的是單線程模式,開發者無法在子線程中更新 UI,所以系統給我提供了 Handler 這個類來實現 UI 更新問題。本貼主要說明 Handler 的工作流程。
1. Handler 的作用
在Android為了保障線程安全,規定只能由主線程來更新UI信息。而在實際開發中,會經常遇到多個子線程都去操作UI信息的情況,那么就會導致UI線程不安全。這時,我們就需要借助 Handler 作為媒介,讓 Handler 通知主線程按順序一個個去更新UI,避免UI線程不安全。
那么,子線程要更新UI的信息時,我們就需要將要更新的消息傳遞到 UI
主線程中,再由主線程完成更新,從而實現工作線程對UI
的更新處理,最終完成異步消息的處理(如圖1所示)。
圖1 - 消息傳遞流程
2. Handler 相關概念解釋
主要涉及的有:處理器(Handler)、消息(Message)、消息隊列(Message Queue)、循環器(Looper)。
概念 |
定義 |
作用 |
備注 |
主線程 (Main Thread) |
當應用第一次啟動時, 就會開啟一條主線程。 |
處理與UI相關的事件 | 主線程 ↑ 通訊媒介:Handler ↓ 子線程 |
子線程 | 人為手動開啟的 | 執行耗時的操作 (如,網絡請求等) |
|
消息 (Message) |
線程間通訊的數據單元 (即Handler接受/處理的對象) |
存儲需要操作的信息 | |
消息隊列 (Message Queue) |
一種數據結構 (隊:先進先出) |
存儲Handler發來的消息 (Message) |
|
處理者 (Handler) |
◆ 主線程與子線程的通訊媒介; ◆ 線程消息的處理者。 |
◆ 添加消息(Message)到消息隊列(Message Queue); ◆ 處理由循環器(Looper)分配過來的消息(Message)。 |
|
循環器 (Looper) |
消息隊列(Message Queue)與 Handler的通訊媒介 |
消息循環即: ◆ 消息獲取:循環取出消息隊列(Message Queue)中的消息(Message); ◆ 消息分發:將取出的消息(Message)發送給對應的處理者(Handler)。 |
3. 工作原理及流程
Handler 機制流程主要包含4個步驟:
① 異步通訊;
② 消息發送;
③ 消息循環;
④ 消息處理。
詳情如下表所示:
步驟 | 具體描述 | 備注 |
---|---|---|
① 異步通訊 | 在主線程中創建: ◆ 處理器對象(Looper) ◆ 消息隊列對象(Message Queue) ◆ Handler對象 |
◆ Looper、Message Queue均屬於主線程; ◆ 創建完Message Queue后,Looper自動進行消息循環; ◆ 此時,Handler自動綁定到主線程的Looper和Message Queue。 |
② 消息發送 | 子線程通過Handler發送消息消息(Message)到消息隊列(Message Queue)中。 | 消息內容 = 子線程對UI的操作 |
③ 消息循環 | ◆ 消息出隊:Looper從消息隊列(Message Queue)中循環取出消息(Message); ◆ 消息分發:Looper將取出的消息(Message)分發給消息的處理者(Handler)。 |
在消息循環過程中,如果消息隊列為空,則自動阻塞。 |
④ 消息處理 | ◆ 處理者(Handler)接受到處理器(Looper)發送過來的消息(Message); ◆ 處理者(Handler)根據消息(Message)進行處理。 |
工作流圖(如圖2所示):
圖2 - Handler 機制工作流圖
4. 總結
最后需要注意幾點:
線程(Thread)、循環器(Looper)、處理器(Handler)之間的關系如下:
- 一個線程(Thread)只能綁定一個循環器(Looper);但一個Thread可以有多個處理器(Handler)。
- 一個循環器(Looper)可綁定多個處理器(Handler)。
- 一個處理器(Handler)只能綁定一個循環器(Looper)。
圖3 - Thread、Looper、Handler 之間的關系