目录
- 正文
- 广播的注册
- 广播的解注册
- 广播的发送
- 总结
正文
本文整体阅读下来相对Activity和Service的启动流程较容易,比较贴近我们日常代码开发习惯。我们曾经有个整机项目,多个APP跨进程交互,本来想采用AIDL进行的,但最终考虑到项目工期和其他同事的能力,最终在采用广播方式进行IPC。
那时,自己也在想,这么多个APP相互发信息,数据量也大,对整机性能有影响么?会不会存在丢失和内存问题。一脸茫然,网上也不会有类似信息告诉总结这种情况,本文也不会总结这个答案,因为看完之后心中自然有数了。
在AMS中持有集合用于存储所有的广播,应用程序可以从向其注册和解注册广播。当应用发送广播时,AMS检查相关权限和特殊的Intent。然后再根据对应IntentFilter匹配到一个或多个Receiver,在应用进程回调其onReceive函数。
阅读源码本身就是一份苦活,不可能一次就读懂,或者了解透的。只有反复的阅读,输入与输出,才会越来越轻松。所以个人建议,先粗读,了解个大概的思路就行。收藏或点赞,等自己ready,再好好结合源码阅读。一定要Fuck Code!
广播的注册
我们常在Activity或Service、甚至Application中调用registerReceiver函数来注册动态广播,该函数其实来自它们共同的父类ContextWrapper中。ContextWrapper是Context的子类,我们会在介绍Context的文章介绍它们的关系。
public Intent registerReceiver( | |
BroadcastReceiver receiver, IntentFilter filter) { | |
return mBase.registerReceiver(receiver, filter); | |
} |
这里Context类型的mBase,在Activity的创建过程实际被赋值为ContextImpl实例。
public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter) { | |
return registerReceiver(receiver, filter, null, null); | |
} | |
public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter, | |
String broadcastPermission, Handler scheduler) { | |
return registerReceiverInternal(receiver, getUserId(), | |
filter, broadcastPermission, scheduler, getOuterContext(),); | |
} |
经过registerReceiver重载函数,调用了registerReceiverInternal函数。
private Intent registerReceiverInternal(BroadcastReceiver receiver, int userId, | |
IntentFilter filter, String broadcastPermission, | |
Handler scheduler, Context context, int flags) { | |
IIntentReceiver rd = null; | |
//分析一 | |
if (receiver != null) { | |
if (mPackageInfo != null && context != null) { | |
if (scheduler == null) { | |
scheduler = mMainThread.getHandler(); | |
} | |
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 { | |
分析二: | |
final Intent intent = ActivityManager.getService().registerReceiverWithFeature( | |
mMainThread.getApplicationThread(), mBasePackageName, getAttributionTag(), rd, | |
filter, broadcastPermission, userId, flags); | |
if (intent != null) { | |
intent.setExtrasClassLoader(getClassLoader()); | |
intent.prepareToEnterProcess(); | |
} | |
return intent; | |
} catch (RemoteException e) { | |
throw e.rethrowFromSystemServer(); | |
} | |
} |
分析一:
传递进来的BroadcastReceiver不为null,LoadedApk类型的mPackageInfo只要应用进程启动,该属性就会被赋值,context这里指向Activity。scheduler为null,赋值为主线程的H类型mH对象。分析一,主要通过上面的变量来获得IIntentReceiver类型rd对象。
getReceiverDispatcher函数先从缓存检测是否有相同类型的BroadcastReceiver对应的ReceiverDispatcher。没有的话,则新建并缓存起来。 一个context对应多个BroadcastReceiver,而一个BroadcastReceiver对应用一个ReceiverDispatcher。
ReceiverDispatcher是LoadedDispatcher的静态内部类,其内部还有一个AIDL类型本地实现静态类InnerReceiver。在ReceiverDispatcher的构造函数中会创建InnerReceiver的实例。
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 = mReceivers.get(context); | |
if (map != null) { | |
rd = map.get(r); | |
} | |
} | |
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); | |
} | |
map.put(r, rd); | |
} | |
} else { | |
rd.validate(context, handler); | |
} | |
rd.mForgotten = false; | |
return rd.getIIntentReceiver(); | |
} | |
} |
回到registerReceiverInternal函数的分析二,调用了AMS的registerReceiverWithFeature函数。
该函数是Broadcast整个注册过程结束的地方,根据新注册的BroadcastReceiver,处理粘性广播的发送和当前注册Receiver的添加。
分析一:
粘性广播存储在AMS的SparseArray<ArrayMap<String, ArrayList<Intent>>>类型的 mStickyBroadcasts中。SparseArray的key为userId,而ArrayMap的key为action,value为Intent。即我们可以通过用户id在mStickyBroadcasts找到当前进程对应所有粘性广播(和针对所有进程的粘性广播),然后根据对应的action找到对应的Intent。这里将他们收集到stickyIntents集合中。
分析二:
所有广播的接收者BroacastReceiver存储在AMS类 HashMap<IBinder, ReceiverList>类型的mRegisteredReceivers中。这里的IBinder类型就是应用进程前面创建的InnerReceiver类实例在AMS的引用。因为广播接收者BroadcastReceiver对应一个或多个Broadcast,所以这里通过继承自ArrayList<BroadcastFilter>的ReceiverList来表达这种关系。通过BroadcastFilter来表示当前接收者感兴趣的广播。
分析三:
对匹配到的粘性Intent进入广播队列广播。
public Intent registerReceiverWithFeature(IApplicationThread caller, String callerPackage, | |
String callerFeatureId, IIntentReceiver receiver, IntentFilter filter, | |
String permission, int userId, int flags) { | |
enforceNotIsolatedCaller("registerReceiver"); | |
//粘性IntentArrayList<Intent> stickyIntents = null; | |
ProcessRecord callerApp = null; | |
final boolean visibleToInstantApps | |
= (flags & Context.RECEIVER_VISIBLE_TO_INSTANT_APPS) !=; | |
int callingUid; | |
int callingPid; | |
boolean instantApp; | |
synchronized(this) { | |
if (caller != null) { | |
//获得当前引用进程的ProcessRecord | |
callerApp = getRecordForAppLocked(caller); | |
... | |
callingUid = callerApp.info.uid; | |
callingPid = callerApp.pid; | |
} else { | |
callerPackage = null; | |
callingUid = Binder.getCallingUid(); | |
callingPid = Binder.getCallingPid(); | |
} | |
//是否快应用(类似小程序) instantApp = isInstantApp(callerApp, callerPackage, callingUid); | |
userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true, | |
ALLOW_FULL_ONLY, "registerReceiver", callerPackage); | |
//分析一:当前注册广播中感兴趣的action列表 Iterator<String> actions = filter.actionsIterator(); | |
if (actions == null) { | |
ArrayList<String> noAction = new ArrayList<String>(); | |
noAction.add(null); | |
actions = noAction.iterator(); | |
} | |
//从历史粘性广播中查找与当前注册的action一致的intent //添加到stickyIntents | |
// Collect stickies of users | |
int[] userIds = { UserHandle.USER_ALL, UserHandle.getUserId(callingUid) }; | |
while (actions.hasNext()) { | |
String action = actions.next(); | |
for (int id : userIds) { | |
ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(id); | |
if (stickies != null) { | |
ArrayList<Intent> intents = stickies.get(action); | |
if (intents != null) { | |
if (stickyIntents == null) { | |
stickyIntents = new ArrayList<Intent>(); | |
} | |
stickyIntents.addAll(intents); | |
} | |
} | |
} | |
} | |
} | |
//处理content类型的Intent ArrayList<Intent> allSticky = null; | |
if (stickyIntents != null) { | |
final ContentResolver resolver = mContext.getContentResolver(); | |
// Look for any matching sticky broadcasts... | |
for (int i =, N = stickyIntents.size(); i < N; i++) { | |
Intent intent = stickyIntents.get(i); | |
// Don't provided intents that aren't available to instant apps. | |
if (instantApp && | |
(intent.getFlags() & Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS) ==) { | |
continue; | |
} | |
//当前注册广播IntentFilter是否与action一致的intent的匹配 | |
//处理content类型 | |
if (filter.match(resolver, intent, true, TAG) >=) { | |
if (allSticky == null) { | |
allSticky = new ArrayList<Intent>(); | |
} | |
allSticky.add(intent); | |
} | |
} | |
} | |
//receiver为null,直接返回null或者第一个粘性intent | |
Intent sticky = allSticky != null ? allSticky.get() : null; | |
if (receiver == null) { | |
return sticky; | |
} | |
synchronized (this) { | |
... | |
//分析二: | |
//从缓存或新建ReceiverList对象,与Receiver绑定 ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder()); | |
if (rl == null) { | |
rl = new ReceiverList(this, callerApp, callingPid, callingUid, | |
userId, receiver); | |
if (rl.app != null) { | |
final int totalReceiversForApp = rl.app.receivers.size(); | |
if (totalReceiversForApp >= MAX_RECEIVERS_ALLOWED_PER_APP) { | |
throw new IllegalStateException("Too many receivers, total of " | |
+ totalReceiversForApp + ", registered for pid: " | |
+ rl.pid + ", callerPackage: " + callerPackage); | |
} | |
//添加到ProcessRecord记录中 | |
rl.app.receivers.add(rl); | |
} else { | |
try { | |
receiver.asBinder().linkToDeath(rl,); | |
} catch (RemoteException e) { | |
return sticky; | |
} | |
rl.linkedToDeath = true; | |
} | |
mRegisteredReceivers.put(receiver.asBinder(), rl); | |
} | |
... | |
//新建BroadcastFilter,并添加到BroadcastList BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage, callerFeatureId, | |
permission, callingUid, userId, instantApp, visibleToInstantApps); | |
if (rl.containsFilter(filter)) { | |
... | |
} else { | |
rl.add(bf); | |
//添加到接收者解析器 | |
mReceiverResolver.addFilter(bf); | |
} | |
// Enqueue broadcasts for all existing stickies that match | |
// this filter. | |
//分析三:对匹配到action的粘性广播进行广播 | |
if (allSticky != null) { | |
ArrayList receivers = new ArrayList(); | |
receivers.add(bf); | |
final int stickyCount = allSticky.size(); | |
for (int i =; i < stickyCount; i++) { | |
Intent intent = allSticky.get(i); | |
BroadcastQueue queue = broadcastQueueForIntent(intent); | |
BroadcastRecord r = new BroadcastRecord(queue, intent, null, | |
null, null, -, -1, false, null, null, OP_NONE, null, receivers, | |
null,, null, null, false, true, true, -1, false, | |
false /* only PRE_BOOT_COMPLETED should be exempt, no stickies */); | |
queue.enqueueParallelBroadcastLocked(r); | |
queue.scheduleBroadcastsLocked(); | |
} | |
} | |
return sticky; | |
} | |
} |
广播的解注册
回到ContextWrapper的unregisterReceiver函数。
public void unregisterReceiver(BroadcastReceiver receiver) { | |
mBase.unregisterReceiver(receiver); | |
} | |
public void unregisterReceiver(BroadcastReceiver receiver) { | |
if (mPackageInfo != null) { | |
IIntentReceiver rd = mPackageInfo.forgetReceiverDispatcher( | |
getOuterContext(), receiver); | |
try { | |
ActivityManager.getService().unregisterReceiver(rd); | |
} catch (RemoteException e) { | |
throw e.rethrowFromSystemServer(); | |
} | |
} else { | |
throw new RuntimeException("Not supported in system context"); | |
} | |
} |
这里通过receiver和context获得IIntentReceiver实例rd,然后调用AMS的unregisterReceiver函数。其中LoadedApk的forgetReceiverDispatcher函数,主要是从mReceivers获取IIntentReceiver的实例,并将receiver对应的内容从缓存移除。
AMS的unregisterReceiver函数。主要是将注册过程添加到mRegisteredReceivers、ProcessProcess.Receivers、mReceiverResolver中对应的内容移除。并终止正在发送的广播。
public void unregisterReceiver(IIntentReceiver receiver) { | |
... | |
final long origId = Binder.clearCallingIdentity(); | |
try { | |
boolean doTrim = false; | |
synchronized(this) { | |
//获得当前对应的ReceiverList | |
ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder()); | |
if (rl != null) { | |
//默认情况为null,看看广播发送是否会赋值 | |
//从处理逻辑来看,就是广播内容 | |
final BroadcastRecord r = rl.curBroadcast; | |
if (r != null && r == r.queue.getMatchingOrderedReceiver(r)) { | |
final boolean doNext = r.queue.finishReceiverLocked( | |
r, r.resultCode, r.resultData, r.resultExtras, | |
r.resultAbort, false); | |
if (doNext) { | |
doTrim = true; | |
r.queue.processNextBroadcast(false); | |
} | |
} | |
//从processRecord中移除 | |
if (rl.app != null) { | |
rl.app.receivers.remove(rl); | |
} | |
//从mRegisteredReceivers和mReceiverResolver移除 | |
removeReceiverLocked(rl); | |
if (rl.linkedToDeath) { | |
rl.linkedToDeath = false; | |
rl.receiver.asBinder().unlinkToDeath(rl,); | |
} | |
} | |
} | |
// If we actually concluded any broadcasts, we might now be able | |
// to trim the recipients' apps from our working set | |
if (doTrim) { | |
trimApplications(OomAdjuster.OOM_ADJ_REASON_FINISH_RECEIVER); | |
return; | |
} | |
} finally { | |
Binder.restoreCallingIdentity(origId); | |
} | |
} | |
void removeReceiverLocked(ReceiverList rl) { | |
mRegisteredReceivers.remove(rl.receiver.asBinder()); | |
for (int i = rl.size() -; i >= 0; i--) { | |
mReceiverResolver.removeFilter(rl.get(i)); | |
} | |
} |
广播的发送
定位到ContextWrapper的sendBroadcast函数。
public void sendBroadcast(Intent intent) { | |
mBase.sendBroadcast(intent); | |
} | |
public void sendBroadcast(Intent intent) { | |
warnIfCallingFromSystemProcess(); | |
String resolvedType = intent.resolveTypeIfNeeded(getContentResolver()); | |
try { | |
intent.prepareToLeaveProcess(this); | |
ActivityManager.getService().broadcastIntentWithFeature(mMainThread.getApplicationThread(), getAttributionTag(), intent, resolvedType,null, Activity.RESULT_OK, null, null, null, AppOpsManager.OP_NONE, null, false,false, getUserId()); | |
} catch (RemoteException e) { | |
throw e.rethrowFromSystemServer(); | |
} | |
} |
调用AMS的broadcastIntentWithFeature函数。内部又调用了broadcastIntentLocked函数。是所有Intent处理的地方,很长很长。有对特殊类型的Intent处理,例如Intent.ACTION_PACKAGE_REMOVED和Intent.ACTION_TIME_CHANGED。该函数主要将有序和无序广播接收者(匹配Intent)添加到receivers列表,并创建BroadcastRecord对象r,持有receivers列表。并根据intent获得对应的广播队列queue,将r添加到queue中,执行queue.scheduleBroadcastsLocked函数。
#AMS xxm | |
@GuardedBy("this") | |
final int broadcastIntentLocked(ProcessRecord callerApp, String callerPackage, | |
@Nullable String callerFeatureId, Intent intent, String resolvedType, | |
IIntentReceiver resultTo, int resultCode, String resultData, | |
Bundle resultExtras, String[] requiredPermissions, int appOp, Bundle bOptions, | |
boolean ordered, boolean sticky, int callingPid, int callingUid, int realCallingUid, | |
int realCallingPid, int userId, boolean allowBackgroundActivityStarts, | |
@Nullable int[] broadcastWhitelist) { | |
intent = new Intent(intent); | |
... | |
int[] users; | |
if (userId == UserHandle.USER_ALL) { | |
// Caller wants broadcast to go to all started users. | |
users = mUserController.getStartedUserArray(); | |
} else { | |
// Caller wants broadcast to go to one specific user. | |
users = new int[] {userId}; | |
} | |
// Figure out who all will receive this broadcast. | |
List receivers = null; | |
List<BroadcastFilter> registeredReceivers = null; | |
// Need to resolve the intent to interested receivers... | |
if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) | |
==) { | |
receivers = collectReceiverComponents( | |
intent, resolvedType, callingUid, users, broadcastWhitelist); | |
} | |
if (intent.getComponent() == null) { | |
if (userId == UserHandle.USER_ALL && callingUid == SHELL_UID) { | |
// Query one target user at a time, excluding shell-restricted users | |
for (int i =; i < users.length; i++) { | |
if (mUserController.hasUserRestriction( | |
UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) { | |
continue; | |
} | |
//查询已注册的Receiver,在注册过程会被添加 | |
List<BroadcastFilter> registeredReceiversForUser = | |
mReceiverResolver.queryIntent(intent, | |
resolvedType, false /*defaultOnly*/, users[i]); | |
if (registeredReceivers == null) { | |
registeredReceivers = registeredReceiversForUser; | |
} else if (registeredReceiversForUser != null) { | |
registeredReceivers.addAll(registeredReceiversForUser); | |
} | |
} | |
} else { | |
//查询已注册的Receiver,在注册过程会被添加 | |
registeredReceivers = mReceiverResolver.queryIntent(intent, | |
resolvedType, false /*defaultOnly*/, userId); | |
} | |
} | |
final boolean replacePending = | |
(intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) !=; | |
... | |
int NR = registeredReceivers != null ? registeredReceivers.size() :; | |
if (!ordered && NR >) { | |
... | |
//通过intent获得广播队列 | |
final BroadcastQueue queue = broadcastQueueForIntent(intent); | |
//将所有数据都封装到BroadcastRecord中 | |
BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, callerPackage, | |
callerFeatureId, callingPid, callingUid, callerInstantApp, resolvedType, | |
requiredPermissions, appOp, brOptions, registeredReceivers, resultTo, | |
resultCode, resultData, resultExtras, ordered, sticky, false, userId, | |
allowBackgroundActivityStarts, timeoutExempt); | |
... | |
final boolean replaced = replacePending | |
&& (queue.replaceParallelBroadcastLocked(r) != null); | |
if (!replaced) { | |
//将广播添加到queue的mParallelBroadcasts数组列表中 | |
queue.enqueueParallelBroadcastLocked(r); | |
queue.scheduleBroadcastsLocked(); | |
} | |
registeredReceivers = null; | |
NR =; | |
} | |
... | |
return ActivityManager.BROADCAST_SUCCESS; | |
} |
enqueueParallelBroadcastLocked函数将BroadcastRecord对象r添加到ArrayList类型的mParallelBroadcasts,后续执行队列事务会从其中取出。
scheduleBroadcastsLocked函数。调用BroadcastHandler类型的mHandler发送一个BROADCAST_INTENT_MSG消息。
public void scheduleBroadcastsLocked() { | |
if (mBroadcastsScheduled) { | |
return; | |
} | |
mHandler.sendMessage(mHandler.obtainMessage(BROADCAST_INTENT_MSG, this)); | |
mBroadcastsScheduled = true; | |
} |
BroadcastHandler的handleMessage函数。执行了processNextBroadcast函数。
public void handleMessage(Message msg) { | |
switch (msg.what) { | |
case BROADCAST_INTENT_MSG: { | |
processNextBroadcast(true); | |
} break; | |
case BROADCAST_TIMEOUT_MSG: { | |
synchronized (mService) { | |
broadcastTimeoutLocked(true); | |
} | |
} break; | |
} | |
} |
processNextBroadcast函数内容太长了,主要是将粘性广播和无序广播发送给接收者。这里只看函数前半部分对无序广播的处理。其中无序广播是从mParallelBroadcasts取出所有广播,并遍历每个广播的过滤器filter,将广播和广播filter传递给deliverToRegisteredReceiverLocked函数
if (fromMsg) { | |
mBroadcastsScheduled = false; | |
} | |
//遍历无序广播数组 | |
while (mParallelBroadcasts.size() >) { | |
r = mParallelBroadcasts.remove(); | |
... | |
final int N = r.receivers.size(); | |
... | |
for (int i=; i<N; i++) { | |
Object target = r.receivers.get(i); | |
//开始传递广播 | |
deliverToRegisteredReceiverLocked(r, (BroadcastFilter)target, false, i); | |
} | |
addBroadcastToHistoryLocked(r); | |
} |
deliverToRegisteredReceiverLocked函数。主要进行权限检查。
#BroadcastQueue xxm | |
private void deliverToRegisteredReceiverLocked(BroadcastRecord r, | |
BroadcastFilter filter, boolean ordered, int index) { | |
boolean skip = false; | |
... | |
//广播filter进行权限检查,不通过skip=true | |
... | |
if (skip) { | |
r.delivery[index] = BroadcastRecord.DELIVERY_SKIPPED; | |
return; | |
} | |
... | |
r.delivery[index] = BroadcastRecord.DELIVERY_DELIVERED; | |
... | |
performReceiveLocked(filter.receiverList.app, filter.receiverList.receiver, | |
new Intent(r.intent), r.resultCode, r.resultData, | |
r.resultExtras, r.ordered, r.initialSticky, r.userId); | |
... | |
} |
performReceiveLocked函数。如果接收者所在的进程已经启动,直接调用 app.thread.scheduleRegisteredReceiver,如果未启动,则直接回调 receiver.performReceive。
#BroadcastQueue xxm | |
void performReceiveLocked(ProcessRecord app, IIntentReceiver receiver, | |
Intent intent, int resultCode, String data, Bundle extras, | |
boolean ordered, boolean sticky, int sendingUser) | |
throws RemoteException { | |
if (app != null) { | |
if (app.thread != null) { | |
try { | |
app.thread.scheduleRegisteredReceiver(receiver, intent, resultCode, | |
data, extras, ordered, sticky, sendingUser, app.getReportedProcState()); | |
} catch (RemoteException ex) { | |
synchronized (mService) { | |
app.scheduleCrash("can't deliver broadcast"); | |
} | |
throw ex; | |
} | |
} else { | |
throw new RemoteException("app.thread must not be null"); | |
} | |
} else { | |
receiver.performReceive(intent, resultCode, data, extras, ordered, | |
sticky, sendingUser); | |
} | |
} |
如果进程已经启动,则调用ApplicationThread的scheduleRegisteredReceiver函数。
public void scheduleRegisteredReceiver(IIntentReceiver receiver, Intent intent, | |
int resultCode, String dataStr, Bundle extras, boolean ordered, | |
boolean sticky, int sendingUser, int processState) throws RemoteException { | |
updateProcessState(processState, false); | |
receiver.performReceive(intent, resultCode, dataStr, extras, ordered, | |
sticky, sendingUser); | |
} |
调用了LoadedApk.ReceiverDispatcher.InnerReceiver类的performReceive函数。
public void performReceive(Intent intent, int resultCode, String data, | |
Bundle extras, boolean ordered, boolean sticky, int sendingUser) { | |
final LoadedApk.ReceiverDispatcher rd; | |
if (intent == null) { | |
rd = null; | |
} else { | |
rd = mDispatcher.get(); | |
} | |
if (rd != null) { | |
//分析一 | |
rd.performReceive(intent, resultCode, data, extras, | |
ordered, sticky, sendingUser); | |
} else { | |
IActivityManager mgr = ActivityManager.getService(); | |
try { | |
if (extras != null) { | |
extras.setAllowFds(false); | |
} | |
mgr.finishReceiver(this, resultCode, data, extras, false, intent.getFlags()); | |
} catch (RemoteException e) { | |
throw e.rethrowFromSystemServer(); | |
} | |
} | |
} |
调用了分析 一ReceiverDispatcher的performReceive函数
public void performReceive(Intent intent, int resultCode, String data, | |
Bundle extras, boolean ordered, boolean sticky, int sendingUser) { | |
//分析 | |
final Args args = new Args(intent, resultCode, data, extras, ordered, | |
sticky, sendingUser); | |
... | |
//分析 | |
if (intent == null || !mActivityThread.post(args.getRunnable())) { | |
if (mRegistered && ordered) { | |
IActivityManager mgr = ActivityManager.getService(); | |
args.sendFinished(mgr); | |
} | |
} | |
} |
ReceiverDispatcher.performReceive函数中分析1将相关数据封装成内部类Args类型的args,然后在分析2通过Handler类型的mActivityThread执行getRunnable返回的Runable对象的run函数。这时切换到应用进程的主线程。
Args.getRunnable函数回调了我们注册广播是复写的onReceiver函数。
public final Runnable getRunnable() { | |
return () -> { | |
... | |
ClassLoader cl = mReceiver.getClass().getClassLoader(); | |
intent.setExtrasClassLoader(cl); | |
intent.prepareToEnterProcess(); | |
setExtrasClassLoader(cl); | |
receiver.setPendingResult(this); | |
//调用广播接收者的onReceive | |
receiver.onReceive(mContext, intent); | |
... | |
} | |
} |
总结
大道至简,所谓注册就是在每个地方维持一个集合,实现所谓的增删改查,根据业务需求增加不同逻辑,例如权限检查,接收者所在进程的状态。