1. 程式人生 > >Android的消息機制

Android的消息機制

系統 接口 以及 end 了解 nbsp log roo sage

1、背景

Handler是Android消息機制的上層接口,通過handler可以輕松地將一個任務切換到Handler所在的線程中去執行。

Handler的作用之一是更新UI,有時候需要在子線程中進行耗時的I/O操作,可能是讀取文件或者訪問網絡等,當耗時操作完成以後可能需要在UI上做一些改變,這時用Handler。

Android的消息機制主要是指Handler的運行機制,Handler的運行需要底層的MessageQueue(消息隊列Looper(消息循環)

的支撐。

消息隊列采用單鏈表的數據結構來存儲消息列表。

Looper以無限循環的形式去查找是否有新消息。Looper中有一個特殊的概念,ThreadLocal,它的作用是在每個線程中存儲數據。

Handler創建的時候回采用當前線程的Looper來構造消息循環系統,那麽Handler內部是通過ThreadLocal來獲取到當前線程的Looper。線程默認沒有Looper,如果需要使用Handler就必須為線程創建Looper。

我們經常提到的主線程,也叫UI線程,就是ActivityThread,ActivityThread被創建的時候就會初始化Looper,這也是在主線程中默認可以使用Handler的原因。

2、Android的消息機制概述

Handler的主要作用是將一個任務切換到某個指定的線程中去執行。系統提供Handler的原因是為了解決在子線程中無法訪問UI的矛盾。

Android規定訪問UI只能在主線程中進行,如果在子線程中訪問UI,那麽程序就會拋出異常。

Android的UI空間不是線程安全的

ViewRootImpl對UI操作做了驗證,這個驗證工作是由ViewRootImpl的checkThread方法來完成的。

通過Handler的post方法將一個Runnable投遞到Handler內部的Looper中去處理。其實post方法最終是通過send方法完成的。

當Handler的send方法被調用時,它會調用MessageQueue的enqueueMessage方法將這個消息放入消息隊列中,然後Looper發現有新消息到來,就會處理這個消息,最終消息中的Runnable或者Handler的handleMessage方法就會被調用。

3、消息隊列的工作原理

消息隊列在Android中指的是MessageQueue,主要包含兩個操作:插入enqueueMessage和讀取next。插入是往消息隊列中插入一條消息,next的作用是從消息隊列中取出一條消息並將其從消息隊列中移除。

MessageQueue是通過一個單鏈表的數據結構來維護消息列表。

next是一個無限循環的方法,如果消息隊列中沒有消息,那麽next方法會一直阻塞在這裏。當有新消息到來時,next方法會返回這條消息並將其從單鏈表中移除。

4、Looper的工作原理

Looper在Android的消息機制總扮演者消息循環的角色,它會不停地從MessageQueue中查看是否有新消息。

Handler的工作需要Looper,沒有Looper的線程就會報錯。通過Looper.prepare()可為當前線程創建一個Looper,接著通過Looper.loop()方法開啟消息循環。

1 Looper.prepare();
2 Handler handler = new Handler();
3 Looper.loop();

5、Handler的工作原理

Handler的工作主要包含消息的發送和接受過程。

消息的發送通過post的一系列方法和send的一系列方法來實現,post的一系列方法最終是通過send的一系列方法來實現的。

Handler發送消息的過程僅僅是向消息隊列中插入了一條消息,MessageQueue的next方法就會返回這條消息給Looper,Looper收到消息就開始處理了,最終消息由Looper交給Handler的dispatchMessage方法處理。

Callback的意義是可以用來創建一個Handler的實例但並不需要派生Handler的子類。

最後,調用handler的handleMessage方法來處理消息。

6、主線程的消息循環

Android的主線程就是ActivityThread,主線程的入口方法是main,在main方法中系統會通過Looper.prepareMainLooper()來創建主線程的Looper以及MessageQueue,並通過Looper.loop()來開啟主線程的消息循環。

主線程的消息循環開始了以後,ActivityThread還需要一個Handler來和消息隊列進行交互,這個Handler就是ActivityThread.H,它內部定義了一組消息類型,主要包含了四大組件的啟動和停止等過程。

ActivityThread通過ApplicationThreadAMS進行進程間通信,AMS以進程間通信的方式完成ActivityThread的請求後會回調ApplicationThread中的Binder方法,然後ApplicationThread會向H發送消息,H收到消息後會將ApplicationThread中邏輯切換到ActivityThread中去執行,即切換到主線程中去執行,這個過程就是主線程的消息循環模型

Android的消息機制