BroadcastReceiver 注册过程
BroadcastReceiver 注册的过程大致如下图所示:
+----------------+ +-------------+ +-------------------------+ +------------------------+
| ContextWrapper | | ContextImpl | | LoadedApk(mPackageInfo) | | ActivityManagerService |
+-----+----------+ +------+------+ +------------+------------+ +---------------+--------+
| | | |
| | | |
registerReceiver| | | |
| | | |
+---------------> | | |
| registerReceiver| | |
| | | |
+------------------------> | |
| | getReceiverDispatcher | |
| | | |
| +---------------------------> |
| | | |
| | [IIntentReceiver] | |
| | | |
| <---------------------------+ registerReceiver |
| | | |
| +------------------------------------------------------------->
| | | |
| | | |
v v v v
调用ContextWrapper的registerReceiver方法,然后传入receiver实例和filter实例。
调用ContextImpl的registerReceiverInternal方法, 由LoadedApk类将context、receiver、scheduler(receiver所在进程的handler)等包装成ReceiverDispatcher类。并将其内部类IIntentReceiver返回,传给ActivityManagerService进行注册。
LoadeApk中与BroadcastReceiver注册相关的类结构图如下所示:
+-------------------------------------------------------------+
| LoadedApk |
| |
| +-------------------+ |
| | mReceivers | +-----------------------+ |
| +-------------------+ | receiver1->dispatcher | |
| | context(Activity)+--------> | |
| | | | receiver2->dispatcher | |
| | context | | | |
| | | | receiver3->dispatcher | |
| | context | | | |
| | | | ... | |
| | ... | +-----------------------+ |
| +-------------------+ |
| |
| |
+-------------------------------------------------------------+
LoadedApk中保存着context与其注册的各个receiver的对应关系,同时也保存着每个receiver与其dispatcher的对应关系。
dispatcher中的IIntentReceiver是与ActivityManagerService沟通的桥梁。其内部结构如下图所示:
+--------------------------------------------------+
| ReceiverDispatcher |
| +-------------------------------------------+ |
| | InnerReceiver extends IIntentReceiver.Stub| |
| +-------------------------------------------+ |
| |
| BroadcastReceiver mReceiver; |
| Context mContext; |
| Handler mActivityThread; |
| |
+--------------------------------------------------+
ActivityManagerService在其registerReceiver方法中,将传入的IIntentReceiver和filter以及caller保存成如下所示的结构:
+---------------------------------------------------------------------------+
| |
| ActivityManagerService |
| +---------------------+ |
| | ReceiverList | |
| +-------------+ +---------------------+ |
| +-->InnerReceiver+--> BroadcastFilter1 | |
| +---------------------+ | +-------------+ | | |
| | mRegisteredReceivers+--+ | BroadcastFilter2 | |
| +---------------------+ | | | |
| | +-------------+ | ... | |
| +-->InnerReceiver| +---------------------+ |
| | +-------------+ |
| | |
| | |
| +--> ... |
| |
| |
| +------------------+ |
| +-------------------+ | BroadcastFilter1 | |
| | mReceiverResolver +---> | |
| +-------------------+ | BroadcastFilter2 | |
| | | |
| | ... | |
| +------------------+ |
| |
+---------------------------------------------------------------------------+
保存成这种结构的原因是为后面发送Broadcast提供高效的实现。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。