標籤:
Android源碼分析——廣播
廣播是一種在組件之間進行訊息傳遞的方式。廣播機制的實現是基於Binder處理序間通訊。
Binder處理序間通訊和廣播的差別:Binder中,Client組件和Service組件通訊之前必須先獲得Service的一個代理對象,Client組件事先要知道Service組件的存在。廣播寄件者事先是不要知道廣播接收者的存在。因此,廣播寄件者和接收者之間的耦合度較低。
廣播是基於訊息發布和訂閱者模型實現的。
在同等情況下,動態註冊的廣播接收者要比靜態註冊的廣播接收者優先收到廣播。
android.intent.action.SCREEN_OFF android.intent.action.SCREEN_ON,這兩個類型的廣播只能被動態註冊的接收器處理
發送方如何指定該廣播可以被誰接收:設定自訂許可權。
廣播接收者的註冊過程
ContextWrapper.registerReceiver
ContextImpl. registerReceiver
ActivityManagerProxy.registerReceiver
ActivityManagerService.registerReceiver
廣播的發送過程廣播發送主要過程:
- 廣播寄件者將一個廣播發送給AMS。
- AMS接收到一個廣播後,首先找到這個廣播的接收者,然後將他們添加到一個廣播調度隊列中,最後向AMS所在的線程訊息佇列發送一個類型為BROADCAST_INTENT_MSG的訊息。
- 當AMS所線上程訊息佇列中的BROADCAST_INTENT_MSG訊息被處理時,AMS就會從廣播調度隊列中找到需要接收廣播的廣播接收者,並將對應的廣播發送給他們所在的進程。
- 廣播接收者所運行在的應用程式進程接收到AMS發送過來的廣播之後,將廣播封裝成一個訊息,並發送到主線程訊息佇列中。當該訊息被處理時,應用程式進程才會將該廣播發送給相應的廣播接收者處理。
第1步——廣播寄件者將一個廣播發送給AMS:
ContextWrapper.sendBroadcast
ContextImpl.sendBroadcast
ActivityManagerProxy.broadcaseIntent
ActivityManagerService. broadcaseIntent
第2步——尋找目標廣播接收者
ActivityInfo ai = AppGlobals.getPackageManager().getReceiverInfo(intent.getComponent,
STOCK_PM_FLAGS);
If(ai!=null){
Receivers = new ArrayList();
ResolveInfo ri = new ResolveInfo();
Ri.activityInfo = ai;
Receivers.add(ri);
}
AMS通過訊息處理機制將廣播轉寄給目標廣播接收者。
AMS將廣播(無序或有序)封裝為一個廣播轉寄任務,並添加到內部一個有序廣播調度隊列中。
動態註冊廣播接收者、靜態註冊廣播接收者兩個隊列都是按照優先順序從高到低的順序來排列的。
if(curr.getPriority() >= curt.priority)說明如果一個動態註冊的目標廣播接收者和靜態註冊的廣播接收者的優先順序相同,動態註冊的接收者排在前面,即先收到廣播。
ActivityManagerService.scheduleBroadcastLocked發送一個類型為BROADCAST_INTENT_MSG訊息。
第3步——處理AMS發送的訊息
Handler.handleMessage
ActivityManagerService.processNextBroadcast
ActivityManagerService.deliverToRegisteredReceiverLocked
如果BroadcastFilter.requiredPermission的值不為null,那麼就表示ActivityManagerService需要檢查廣播寄件者的許可權。
如果BroadcastRecord對象的成員變數requiredPermission的值不為null,表示AMS需要檢查廣播接收者的許可權。
以上這兩個許可權是調用AMS成員函數checkComponentPermission來檢查對方PID和UID是否符合要求。
ActivityManagerService.performReceiverLocked
第4步——廣播接收者處理MSG
ApplicationThread.scheduleRegisteredReceiver
InnerReceiver.performReceive
ReceiverDispatcher.performReceive
Args.run
BroadcastReceiver.onReceive
Android源碼——Broadcast Receiver