關(guān)于廣播的分發(fā)
關(guān)于A(yíng)ndroid的廣播分發(fā)會(huì)分兩個(gè)篇章來(lái)介紹锻拘,先把結(jié)論放到最前咐熙。
1.對(duì)于廣播注冊(cè)來(lái)說(shuō)篷就,分為靜態(tài)注冊(cè)和動(dòng)態(tài)注冊(cè)弟翘,
分別會(huì)用 ResolveInfo 和 BroadcastFilter 來(lái)實(shí)例化,
2.對(duì)于廣播類(lèi)型莽红,也分有序廣播和普通廣播妥畏。
3.廣播分發(fā),是先發(fā)普通廣播安吁,Parallel Broadcast醉蚁,一次發(fā)給所有 Receiver
然后在發(fā)有序廣播 Serialized Broadcast 的時(shí)候,先發(fā)給動(dòng)態(tài)注冊(cè)的Receiver鬼店,再發(fā)給靜態(tài)注冊(cè)的 Receiver网棍。
而靜態(tài)注冊(cè)的 Receiver 通過(guò) H 去分發(fā)消息。
這部分主要簡(jiǎn)單分析注冊(cè)過(guò)程妇智,
之前的了解結(jié)果确沸,廣播的處理可以在主線(xiàn)程和子線(xiàn)程,
主線(xiàn)程的情況俘陷,
會(huì)在 ActivityThread 的 H.handleMessage 處理從 ApplicationThread 分發(fā)過(guò)來(lái)的廣播消息,
handleReceiver 會(huì)從消息中取出對(duì)應(yīng)的 Receiver 去回調(diào) onReceive 操作
子線(xiàn)程的情況观谦,
需要在注冊(cè)廣播的時(shí)候傳遞一個(gè)子線(xiàn)程 handler 和 receiver進(jìn)去拉盾,
然而胡巴@wx_huhuxjh126 研究過(guò)之后發(fā)現(xiàn)實(shí)際上 handler 不寫(xiě)任何 handleMessage 操作也可以,
ApplicationThread 在分發(fā)時(shí)會(huì)直接運(yùn)行一個(gè)封裝了 receiver 的 runnable 對(duì)象豁状,
也就是說(shuō)不需要通過(guò) handleMessage 來(lái)回調(diào) receiver.onReceive捉偏,
> 前提
分析廣播的分發(fā)有個(gè)前提倒得,需要了解廣播注冊(cè)的時(shí)候到底是注冊(cè)什么到什么,
嗯哼先給出結(jié)論夭禽,
注冊(cè)霞掺,是把一個(gè)實(shí)現(xiàn)了 Binder 類(lèi) IIntentReceiver 的 InnerReceiver 對(duì)象 注冊(cè)到 ActivityManagerServer,
InnerReceiver --持有--> ReceiverDispatch --持有--> BroadcastReceiver 和 Handler
> 注冊(cè)
不管是主線(xiàn)程的handler還是子線(xiàn)程的handler讹躯,
注冊(cè)都是把一個(gè)實(shí)現(xiàn)了 IIntentReceiver 的 InnerReceiver 對(duì)象交給 AMS 去注冊(cè)菩彬,
這段關(guān)于 InnerReceiver 的代碼可以看出來(lái),
InnerReceiver 是一個(gè) IBinder 潮梯,
最終 AMS 也是使用這個(gè)東西來(lái)分發(fā)消息的骗灶。
ReceiverDispatcher,看名字可以猜這個(gè)東西既是用來(lái)接收也用來(lái)分發(fā)廣播
下面順便理一下 Activity 和針對(duì)各個(gè)不同廣播的 Receiver 是怎樣一種對(duì)應(yīng)關(guān)系
在 LoadedApk 中秉馏,
有個(gè)對(duì)象 mReceiver,
ArrayMap<Context, ArrayMap<BroadcastReceiver, LoadedApk.ReceiverDispatcher>>
這貨是用 context 作為 key耙旦, 來(lái)對(duì)應(yīng)上面代碼里這個(gè) map,
ArrayMap<BroadcastReceiver, LoadedApk.ReceiverDispatcher>
而這個(gè) map 是以 receiver 為 key萝究,來(lái)對(duì)應(yīng)各個(gè)不同的 ReceiverDispatcher 的免都,
也就是說(shuō)只要給定一個(gè) activity 和 BroadcastReceiver,就可以找到是否有對(duì)應(yīng)的 ReceiverDispatcher 存在
> 注冊(cè) Binder
這里涉及的是 AIDL 的 Binder 注冊(cè)過(guò)程帆竹,比較簡(jiǎn)單就省略分析了绕娘。
以上,
不涉及動(dòng)態(tài)注冊(cè)的廣播和靜態(tài)注冊(cè)的廣播的區(qū)別馆揉,
這兩者會(huì)在分發(fā)的時(shí)候有不同的邏輯處理业舍。
這里只提一下兩者的 receiver 的不同,
靜態(tài)注冊(cè)的廣播 Receiver 繼承于 ResolverInfo
動(dòng)態(tài)注冊(cè)的廣播 Receiver 繼承于 BroadcastFilter