一:广播的注册过程
广播的动态注册过程是从ContextWrapper的registerReceiver方法开始的.代码如下:
ContextWrapper的registerReceiver方法并没有做实际的工作,而是把注册过程交给了ContextImpl来完成
public Intent registerReceiver(
BroadcastReceiver receiver, IntentFilter filter) {
return mBase.registerReceiver(receiver, filter);
}
下面是ContextImpl的registerRceciver方法:
registerRceciver调用了registerReceiverInternal方法。
public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter) {
return registerReceiver(receiver, filter, null, null);
}
@Override
public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter,
String broadcastPermission, Handler scheduler) {
return registerReceiverInternal(receiver, getUserId(),
filter, broadcastPermission, scheduler, getOuterContext());
}
registerReceiverInternal方法如下:
private Intent registerReceiverInternal(BroadcastReceiver receiver, int userId,
IntentFilter filter, String broadcastPermission,
Handler scheduler, Context context) {
IIntentReceiver rd = null;
if (receiver != null) {
if (mPackageInfo != null && context != null) {
if (scheduler == null) {
scheduler = mMainThread.getHandler();
}
/**
* 系统首先从mPackageInfo获取IIntentReceiver对象。然后采用夸进程的方式向AMS发送
* 广播注册请求。之所以采用IIntentReceiver而不是直接采用BroadcastReceiver,这是
* 因为上述注册过程是一个进程间通信的过程。
*/
rd = mPackageInfo.getReceiverDispatcher(
receiver, context, scheduler,
mMainThread.getInstrumentation(), true);
} else {
if (scheduler == null) {
scheduler = mMainThread.getHandler();
}
rd = new LoadedApk.ReceiverDispatcher(
receiver, context, scheduler, null, true).getIIntentReceiver();
}
}
try {
/**
* 此处调用AMS的registerReceiver。进入服务进程
*/
return ActivityManagerNative.getDefault().registerReceiver(
mMainThread.getApplicationThread(), mBasePackageName,
rd, filter, broadcastPermission, userId);
} catch (RemoteException e) {
return null;
}
}
系统首先从mPackageInfo获取IIntentReceiver对象,然后在采用夸进程的方式向AMS发送广播的注册请求。之所以采用IIntentReceiver二不是直接采用BroadcastReceiver,这是因为上述注册过程是一个进程间通信的过程,而BroadcastReceiver作为Android的一个组件是不能直接跨进程传递的。所以需要通过IIntentReceiver中转一下。毫无疑问,IIntentReceiver必须是一个Binder接口。它的具体实现是LoadedApk.ReceiverDispatcher.InnerReceiver,ReceiverDispatcher内部同时保存了BroadcastReceiver和InnerReceiver,这样当接收到广播时,ReceiverDispatcher可以很方便的调用BroadcastReceiver的onReceiver方法
public IIntentReceiver getReceiverDispatcher(BroadcastReceiver r,
Context context, Handler handler,
Instrumentation instrumentation, boolean registered) {
synchronized (mReceivers) {
LoadedApk.ReceiverDispatcher rd = null;
ArrayMap<BroadcastReceiver, LoadedApk.ReceiverDispatcher> map = null;
if (registered) {
/**
* 根据上下文获取map
*/
map = mReceivers.get(context);
if (map != null) {
/**
* 根据BroadcastReceiver自定义广播获取ReceiverDispatcher
*/
rd = map.get(r);
}
}
/**
* 当没有创建和自定义广播绑定的ReceiverDispatcher则新建ReceiverDispatcher
*/
if (rd == null) {
rd = new ReceiverDispatcher(r, context, handler,
instrumentation, registered);
if (registered) {
if (map == null) {
map = new ArrayMap<BroadcastReceiver, LoadedApk.ReceiverDispatcher>();
mReceivers.put(context, map);
}
/**
* 建立自定义BroadcastReceiver和ReceiverDispatcher的关系
*/
map.put(r, rd);
}
} else {
/**
* 如果已经绑定则检查context和handler是否有变,有变抛出异常
*/
rd.validate(context, handler);
}
rd.mForgotten = false;
/**
* 返回mIIntentReceiver
*
*
*/
return rd.getIIntentReceiver();
}
}
来源:CSDN
作者:finley_feng
链接:https://blog.csdn.net/finley_feng/article/details/103604232