动态广播注册源码笔记
ContextWrapper
1、registerReceiver
@Override
public Intent registerReceiver(
BroadcastReceiver receiver, IntentFilter filter) {
return mBase.registerReceiver(receiver, filter);
}
ContextImpl
1、registerReceiver
public Intent registerReceiver(BroadcastReceiver receiver,
IntentFilter filter,String broadcastPermission,
Handler scheduler, int flags) {
return registerReceiverInternal(receiver, getUserId(),
filter, broadcastPermission, scheduler, getOuterContext(), flags);
}
2、registerReceiverInternal(重要)
这里有一个很重要的类:
LoadedApk.ReceiverDispatcher
,它是LoadedApk
的一个内部类,它持有三个重要的变量:
- 1、
BroadcastReceiver
:我们调用registerReceiver
时候传进来的BroadcastReceiver
- 2、
getOuterContext
:如果我们在Activity
调用registerReceiver
,那这个context
就是来自于Activity
的ContextImpl
;同时这也是为什么我们在onReceive
的时候其中一个参数是Context
- 3、
Handler
:在分发的时候广播接收器并不是直接从AMS
那里拿到发送给它的广播的,而是通过Handler
机制去分发(所以没有绝对的并行广播)
同时
ReceiverDispatcher
还有一个内部类InnerReceiver
,这是一个继承自IIntentReceiver.Stub
同时实现了IInterface
的类,代表这是一个本地Binder对象,它还持有一个弱引用对象WeakReference<LoadedApk.ReceiverDispatcher>
。
也就是说:调用ActivityManager.getService().registerReceiver方法传入的参数InnerReceiver里面包含了receiver、context、handler,然后AMS将其保存在内部List,这也就是为什么在分发广播的时候能找得到对应的接收器。
(关于
Stub
,它和Proxy
一样都是继承了IBinder
同时实现了IInterface
的类,严格来讲Proxy
是通过组合持有IBinder
。说明Stub
和Proxy
具有IPC
能力,而这两者由asInterface
方法根据要通信的进程在本进程还是其他进程来决定调用哪一个)
private Intent registerReceiverInternal(BroadcastReceiver receiver, int userId,
IntentFilter filter, String broadcastPermission,
Handler scheduler, Context context, int flags) {
//这个类很重要,属于ReceiverDispatcher的内部类
//是一个用于通信的IBinder对象
//内部持有一个ReceiverDispatcher的弱引用对象
IIntentReceiver rd = null;
if (receiver != null) {
if (mPackageInfo != null && context != null) {
if (scheduler == null) {
scheduler = mMainThread.getHandler();