Android廣播機制一註冊流程
Broadcast廣播機制--註冊
--許棟樑
一、前言
部落格初開,沒事兒寫寫文章。這是撰寫的第一篇技術性文章。就像你知道我知道的那樣,每個人的第一次都會洋相盡出,漏洞百出。。。但是,那又能怎樣?只有邁出第一步,才能知道自己能走多遠。每篇文章前面都閒扯兩句,一方面,本人不太喜歡開頭就複製貼上原始碼;另一方面,寫技術類文章是相當枯燥的,BB兩句正好緩解緩解。
好吧,開始寫了!另外多說兩句:不必過分在意細節,不要在小範圍內和原始碼死嗑。因此,本文不想描述動態註冊廣播、靜態註冊廣播;不會去解釋mFgBroadcastQueue、mBgBroadcastQueue的區別和用法。
二、文章結構
1、設計模式簡介
2、廣播註冊流程
3、資料結構解釋
三、正文部分
1、設計模式簡介
在介紹具體技術細節之前,我認為還是先要理清整個模組所使用的基本框架結構。搭好架子,才不會陷入無盡的程式碼深淵。站在屋頂,才能一窺全貌。這裡我並不打算描述這些設計模式,而是放在《Android核心原始碼與設計模式》這一部落格分類中具體講解。
Android中的廣播使用的是釋出訂閱者(Subscribe/Publish)模式,或者說是觀察者模式(這兩個模式是否相同?個人感覺這兩者是相通的)。觀察者模式有兩個主體:被觀察物件
從設計模式角度來看:
1)、觀察者即是使用者程式,每個使用者程式可以定義多個廣播接受器。
2)、被觀察物件持有和維護多個使用者程式的BroadcastReceiver列表。這個列表由app_process程序中的BroadcastQueue以用AMS(ActivityManagerService)
從廣播流程上看:
廣播整體流程可以分為4個步驟:註冊、外部輸入、遍歷、通知。
1)、註冊:這裡只涉及到通過registerReceiver()方式註冊的廣播。
2)、外部輸入:使用者程序或者系統中一些程序通過sendBroadcast()傳送廣播。
3)、遍歷:查詢匹配的、感興趣的廣播接受器(觀察者)。
4)、通知:找到後,傳送給目標BroadcastReceiver。
2、廣播註冊流程
如上文所述,這裡只描述通過RegisterReceiver()註冊的廣播過等一下,而通過apk應用程式裡面的AndroidManifest.xml註冊的廣播並不作分析。使用者程序註冊廣播流程時序流程圖如下所示。使用者程序通過registerReceiver呼叫,最後註冊過程會流轉到ActivityManagerProxy中,AMS在使用者程序中的代理。最終的註冊位置還是在遠端程序app_process的AMS中完成。很明顯這裡涉及到程序間通訊,即將註冊轉交給AMS完成。
這裡有沒有必要停下來分析Binder通訊機制?是完全沒有必要的!!!不要一旦遇到某個知識點,就岔開主體跑去分析其它的知識。分析過程不要太擴散,Hold不住的!
在AMS中的廣播註冊過程才是關鍵,這裡似乎必須得貼上一下原始碼才能更好的解釋,但是這裡只複製出核心的程式碼片段。通過下面的流程圖,我們可以清晰的看到,原來mRegisteredeReceivers就是“被觀察物件”ActivityManagerService中持有的“觀察者列表”。我們在unregisterReceiver()中也將看到“觀察者”從這個列表中移除的過程。
3、資料結構解釋
這裡有必要解釋流程圖中提到的各種資料結構的用法。
mRegisteredReceivers,它是一個HashMap,key是IbroadcastReceiver轉化的IBinder物件,value是建立的ReceiverList物件。
我們來看一下mRegisteredReceivers的儲存模型,每個使用者程序中的所有broadcastReceiver都在mRegisteredRecievers中儲存。ReceiverList中記錄了使用者程序的相關資訊,具體資訊是記錄在ProcessRecord(即ReceiverList.app變數中)。
mReceiverResolver,將當前註冊的BroadcastReceiver中的過濾器轉化成的BroadcastFilter新增到其中。作用是在傳送廣播的過程中獲取註冊的廣播接收器。因此最終起到“觀察者列表”作用的就是這個資料結構。上面提到的mRegisterReceivers只不過用來快速判斷當前BroadcastReciever是否已經註冊,並存儲相關資訊。
BroadcastQueue,是用來儲存其它使用者(程序)通過sendBroadcast()發過來的廣播,並且排程這些廣播,並將之發給相應的廣播接收器。
四、結論:
有沒有感覺broadcastReceiver的註冊過程很簡單?