其他
值得一看的Android广播分析好文
本文作者
作者:新小梦
链接:
https://juejin.cn/post/7322156751818522661
本文由作者授权发布。
在AMS中持有集合用于存储所有的广播,应用程序可以从向其注册和解注册广播。当应用发送广播时,AMS检查相关权限和特殊的Intent。然后再根据对应IntentFilter匹配到一个或多个Receiver,在应用进程回调其onReceive函数。
public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter) {
return mBase.registerReceiver(receiver, filter);
}
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(), 0);
}
ContextImpl.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) {
//主线程的H对象,用于接收广播用于保持receivcer广播顺序到达问题
scheduler = mMainThread.getHandler();
}
//注释1:已注册,则获取旧的对象,否则新创建
rd = mPackageInfo.getReceiverDispatcher(
receiver, context, scheduler,
mMainThread.getInstrumentation(), true);
} else {
if (scheduler == null) {
scheduler = mMainThread.getHandler();
}
//注释2
rd = new LoadedApk.ReceiverDispatcher(
receiver, context, scheduler, null, true).getIIntentReceiver();
}
}
try {
//注释3,返回值是第一个匹配IntentFilter的黏性广播的Intent或者null
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();
}
}
AMS.registerReceiverWithFeature
mRegisteredReceivers:AMS的成员变量,类型为HashMap<IBinder, ReceiverList>,Hash Key是IIntentReceiver的IBinder对象,也就是客户端BroadcastReceiver在客户端的代表。而Value就是ReceiverList对象。 ReceiverList:继承自ArrayList<BroadcastFilter>,用于存储BroadcastFilter对象,表示一个BroadReceiver所对应的多个IntenerFilter的关系。 BroadcastFilter: 内部封装了IntentFilter,可以表示为IntentFilter在系统层的代表。 mReceiverResolver:存储BroadcastFilter,表示当前所有的IntentFilter对象。后续发送广播时,如果广播没有component,需要通过它区解析匹配的接收者。
//ContextWrapper
public void unregisterReceiver(BroadcastReceiver receiver) {
mBase.unregisterReceiver(receiver);
}
//ContextImpl
public void unregisterReceiver(BroadcastReceiver receiver) {
if (mPackageInfo != null) {
//LoadedApk
IIntentReceiver rd = mPackageInfo.forgetReceiverDispatcher(
getOuterContext(), receiver);
try {
//AMS
ActivityManager.getService().unregisterReceiver(rd);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
} else {
throw new RuntimeException("Not supported in system context");
}
}
public void unregisterReceiver(IIntentReceiver receiver) {
final long origId = Binder.clearCallingIdentity();
try {
boolean doTrim = false;
synchronized(this) {
ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
if (rl != 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.processNextBroadcastLocked(/* frommsg */ false,
/* skipOomAdj */ true);
}
}
//ProcessRecord移除
if (rl.app != null) {
rl.app.mReceivers.removeReceiver(rl);
}
//从mRegisteredReceivers移除
//从mReceiverResolver移除
removeReceiverLocked(rl);
if (rl.linkedToDeath) {
rl.linkedToDeath = false;
rl.receiver.asBinder().unlinkToDeath(rl, 0);
}
}
//清理进程
if (doTrim) {
trimApplicationsLocked(false, OomAdjuster.OOM_ADJ_REASON_FINISH_RECEIVER);
return;
}
} finally {
Binder.restoreCallingIden
public void sendBroadcast(Intent intent) {
mBase.sendBroadcast(intent);
}
public void sendBroadcast(Intent intent) {
warnIfCallingFromSystemProcess();
String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
try {
intent.prepareToLeaveProcess(this);
//AMS
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();
}
}
1、AMS对广播的处理
携带文件描述符; 系统未启动完毕,当前Intent发送给所有的接收者。 开机升级广播。
public final int broadcastIntentWithFeature(IApplicationThread caller, String callingFeatureId,
Intent intent, String resolvedType, IIntentReceiver resultTo,
int resultCode, String resultData, Bundle resultExtras,
String[] requiredPermissions, String[] excludedPermissions, int appOp, Bundle bOptions,
boolean serialized, boolean sticky, int userId) {
synchronized(this) {
//对广播Intent合法性检查
intent = verifyBroadcastLocked(intent);
final ProcessRecord callerApp = getRecordForAppLOSP(caller);
final int callingPid = Binder.getCallingPid();
final int callingUid = Binder.getCallingUid();
final long origId = Binder.clearCallingIdentity();
try {
//下一个调用,会在调用重载函数
return broadcastIntentLocked(callerApp,
callerApp != null ? callerApp.info.packageName : null, callingFeatureId,
intent, resolvedType, resultTo, resultCode, resultData, resultExtras,
requiredPermissions, excludedPermissions, appOp, bOptions, serialized,
sticky, callingPid, callingUid, callingUid, callingPid, userId);
} finally {
Binder.restoreCallingIdentity(origId);
}
}
}
Instant应用禁止发送广播给Instant应用接收者,即快应用之间禁止通过广播交互。 系统未启动完成(非升级过程),禁止通过广播启动新的进程。 广播发给特定用户,用户或者父用户没有运行,则不发送广播。 广播发送时,设置options数据,需要根据options情况,检查白名单、受限目标、后台启动Activity等权限进行检查。 检查广播Action,判断是否受保护的广播的Action,即声明在framework/base/core/res/AndroidMenifest.xml文件内的protected-broadcast,这些广播只能由系统应用发出,例如息屏android.intent.action.SCREEN_OFF。非系统应用发送这些广播会报异常。同时非系统应用在发送AppWidgetManager.ACTION_APPWIDGET_CONFIGURE或AppWidgetManager.ACTION_APPWIDGET_UPDATE广播时,只能发给自己,这些是操作自己的桌面小组件。 如果当前广播Action属于系统的隐式广播一种,例如ACTION_LOCALE_CHANGED,那么添加上Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND标志,表示广播允许被静态注册的接收者收到。 如果广播Action属于系统的一些特殊广播,需要进行一些特别的处理,例如时间变化ACTION_TIME_CHANGED、ACTION_TIMEZONE_CHANGED;应用相关的变化ACTION_PACKAGE_ADDED、ACTION_PACKAGE_DATA_CLEARED、ACTION_PACKAGE_CHANGED等等很多。
黏性广播 需要检测发送者是否声明BROADCAST_STICKY权限,且该广播不能携带其他权限检查。 不能指定具体的目标组件。即Intent不能设置setComponent函数。 非全局的黏性广播不能与已存在全局的黏性广播相同(冲突)。 黏性广播的处理: 从mStickyBroadcasts获取当前用户所有的黏性广播stickies,我们知道,广播注册时会从mStickyBroadcasts中取出黏性广播发给广播队列进行处理。根据当前黏性广播的action在stickies映射中查询,查看是否有相同action的黏性广播(list集合),如果有且IntentFilter相同,则替代旧的,不相同则添加到list中。也就是说黏性广播发送只会添加到黏性广播容器中,在广播接收者注册时候才被处理。
无序广播 如果当前广播属于普通,无序的,且registerReceiver集合有收集到匹配的接收者。
如果广播发送者是系统应用,需要调用checkBroadcastFromSystem函数检测一下广播的action,做一些警告。 根据Intent的flags获取当前广播属于前台广播队列或后台广播队列。 广播相关信息封装成BroadcastRecord对象,添加到广播队列的并行集合中mParallelBroadcasts,表示接收者之间可以同时处理该广播。 调用广播队列BroadcastQueue的`scheduleBroadcastsLocked`函数。
如果广播是无序广播,那么不会有合并到同一个队列的动作,因为有判断条件。这时候,接下来处理的是无序广播被静态注册接收者处理的部分。 如果广播是有序广播,那么不会执行无序广播的处理逻辑,receivers和registerReceiver被合并在一起。然后就是下面的有序广播处理逻辑。 有序广播
如果广播发送者是系统应用,需要调用checkBroadcastFromSystem函数检测一下广播的action,做一些警告。 根据Intent的flags获取当前广播属于前台广播队列或后台广播队列。 广播相关信息封装成BroadcastRecord对象,添加到广播队列的顺序集合中mOrderedBroadcasts。 调用广播队列BroadcastQueue的`scheduleBroadcastsLocked`函数。
默认会给广播Intent对象添加上Intent.FLAG_EXCLUDE_STOPPED_PACKAGES,表示广播不发送给处于停止状态(没有在运行)的BroadcastReceiver。意味着正常情况下,如果我们程序被退出,将无法接收任何广播。 FLAG_RECEIVER_REGISTERED_ONLY表示广播只能被动态注册的接收者接收。
2、广播队列对广播的处理
//BroadcastQueue xxm
public void scheduleBroadcastsLocked() {
if (mBroadcastsScheduled) {//避免重复执行
return;
}
//BroadcastHandler
mHandler.sendMessage(mHandler.obtainMessage(BROADCAST_INTENT_MSG, this));
mBroadcastsScheduled = true;
}
#BroadcastHandler xxm
public void handleMessage(Message msg) {
switch (msg.what) {
case BROADCAST_INTENT_MSG: {
processNextBroadcast(true);//执行该函数
} break;
case BROADCAST_TIMEOUT_MSG: {
synchronized (mService) {
broadcastTimeoutLocked(true);
}
} break;
}
}
private void processNextBroadcast(boolean fromMsg) {
synchronized (mService) {
processNextBroadcastLocked(fromMsg, false);
}
}
//Broadcast对象r来自mParallelBroadcasts集合,N即为receivers长度
for (int i=0; i<N; i++) {
Object target = r.receivers.get(i);
deliverToRegisteredReceiverLocked(r,
(BroadcastFilter) target, false, i);
}
final long now = SystemClock.uptimeMillis();
//优先获取闹钟广播,接着到期广播,最后有序广播
r = mDispatcher.getNextBroadcastLocked(now);//获取下一个BroadcastRecord
if (r == null) {//没有广播需要处理
...
return;
}
//当前时间超过了广播约定的处理时间,结束该广播
int numReceivers = (r.receivers != null) ? r.receivers.size() : 0;
if (mService.mProcessesReady && !r.timeoutExempt && r.dispatchTime > 0) {
if ((numReceivers > 0) &&
(now > r.dispatchTime + (2 * mConstants.TIMEOUT * numReceivers))) {
//最终调用finishReceiverLocked,参考广播的结束
broadcastTimeoutLocked(false); // forcibly finish this broadcast
forceReceive = true;
r.state = BroadcastRecord.IDLE;
}
}
//广播的默认状态是IDLE,也就是位对广播处理
if (r.state != BroadcastRecord.IDLE) {
return;
}
//四个条件来判断广播在所有的receiver中处理完毕
if (r.receivers == null || r.nextReceiver >= numReceivers
|| r.resultAbort || forceReceive) {
// Send the final result if requested
if (r.resultTo != null) {
boolean sendResult = true;
// splitToken是用于处理延期广播的一个特殊计数
if (r.splitToken != 0) {
int newCount = mSplitRefcounts.get(r.splitToken) - 1;
if (newCount == 0) {
mSplitRefcounts.delete(r.splitToken);
} else {
sendResult = false;
mSplitRefcounts.put(r.splitToken, newCount);
}
}
if (sendResult) {
if (r.callerApp != null) {
mService.mOomAdjuster.mCachedAppOptimizer.unfreezeTemporarily(
r.callerApp);
}
try {
//广播下个处理的地方
performReceiveLocked(r.callerApp, r.resultTo,
new Intent(r.intent), r.resultCode,
r.resultData, r.resultExtras, false, false, r.userId);
r.resultTo = null;
} catch (RemoteException e) {
r.resultTo = null;
}
}
}
//将广播添加到历史消息
cancelBroadcastTimeoutLocked();
addBroadcastToHistoryLocked(r);
if (r.intent.getComponent() == null && r.intent.getPackage() == null
&& (r.intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
mService.addBroadcastStatLocked(r.intent.getAction(), r.callerPackage,
r.manifestCount, r.manifestSkipCount, r.finishTime-r.dispatchTime);
}
mDispatcher.retireBroadcastLocked(r);
r = null;
looped = true;
continue;
}
//在被加入延期广播的时候为true,默认为false
if (!r.deferred) {
//广播下一个接收者的进程uid
final int receiverUid = r.getReceiverUid(r.receivers.get(r.nextReceiver));
//根据uid在mDeferredBroadcasts列表获取是否有延期的广播
if (mDispatcher.isDeferringLocked(receiverUid)) {
BroadcastRecord defer;
if (r.nextReceiver + 1 == numReceivers) {//只有一个接收者,不需要设计splitToken
defer = r;
mDispatcher.retireBroadcastLocked(r);
} else {//多个接收者
//splitRecipientsLocked函数会检查当前广播剩下的receiver,获取于当前receiver相同进程的receiver列表,新建broadcast对象,把receiver列表加到该对象中,也就是这里的defer
defer = r.splitRecipientsLocked(receiverUid, r.nextReceiver);
// Track completion refcount as well if relevant
if (r.resultTo != null) {
int token = r.splitToken;
if (token == 0) {
// 第一次给广播设计splitToken,本质了i++。叠加mSplitRefcounts计数
r.splitToken = defer.splitToken = nextSplitTokenLocked();
mSplitRefcounts.put(r.splitToken, 2);
} else {
//后续只需要增加mSplitRefcounts计数
final int curCount = mSplitRefcounts.get(token);
mSplitRefcounts.put(token, curCount + 1);
}
}
}
//将广播添加到延期队列中,这里deferred会被设置为true;
mDispatcher.addDeferredBroadcast(receiverUid, defer);
r = null;
looped = true;
continue;
}
}
//BroadcastQueue xxm
void performReceiveLocked(ProcessRecord app, IIntentReceiver receiver,
Intent intent, int resultCode, String data, Bundle extras,
boolean ordered, boolean sticky, int sendingUser)
throws RemoteException {
//异步方式调用receiver所在线程scheduleRegisteredReceiver函数
if (app != null) {
if (app.thread != null) {
...
app.thread.scheduleRegisteredReceiver(receiver, intent, resultCode,
data, extras, ordered, sticky, sendingUser, app.getReportedProcState());
...
} else {
//同步方式
receiver.performReceive(intent, resultCode, data, extras, ordered,
sticky, sendingUser);
}
}
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);
}
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) {
//调用performReceive
rd.performReceive(intent, resultCode, data, extras,
ordered, sticky, sendingUser);
} else {//Intent为null,finish掉receiver,逻辑与解注册unregisterReceiver函数相似
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();
}
}
}
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);
...
//分析2
if (intent == null || !mActivityThread.post(args.getRunnable())) {
if (mRegistered && ordered) {//顺序广播
IActivityManager mgr = ActivityManager.getService();
args.sendFinished(mgr);//通知结束
}
}
}
public final Runnable getRunnable() {
return () -> {
//自定义的BroadcastReceiver对象
final BroadcastReceiver receiver = mReceiver;
final boolean ordered = mOrdered;
final IActivityManager mgr = ActivityManager.getService();
final Intent intent = mCurIntent;
mCurIntent = null;
mDispatched = true;
mRunCalled = true;
//广播异常、接收者异常、丢弃
if (receiver == null || intent == null || mForgotten) {
if (mRegistered && ordered) {
sendFinished(mgr);//有序广播的回调
}
return;
}
try {
ClassLoader cl = mReceiver.getClass().getClassLoader();
intent.setExtrasClassLoader(cl);
intent.prepareToEnterProcess(ActivityThread.isProtectedBroadcast(intent,
mContext.getAttributionSource());
setExtrasClassLoader(cl);
//设置了处理结果
receiver.setPendingResult(this);
//回调onReceive函数
receiver.onReceive(mContext, intent);
} catch (Exception e) {
//异常,有序广播通知结束
if (mRegistered && ordered) {
sendFinished(mgr);
}
...
}
//onReceiver函数前设置了
if (receiver.getPendingResult() != null) {
finish();
}
};
}
3、processCurBroadcastLocked
private final void processCurBroadcastLocked(BroadcastRecord r,
ProcessRecord app) throws RemoteException {
final IApplicationThread thread = app.getThread();
...
r.receiver = thread.asBinder();
r.curApp = app;
final ProcessReceiverRecord prr = app.mReceivers;
prr.addCurReceiver(r);
...
// Tell the application to launch this receiver.
r.intent.setComponent(r.curComponent);
boolean started = false;
try {
...
thread.scheduleReceiver(new Intent(r.intent), r.curReceiver,
mService.compatibilityInfoForPackage(r.curReceiver.applicationInfo),
r.resultCode, r.resultData, r.resultExtras, r.ordered, r.userId,
app.mState.getReportedProcState());
started = true;
} finally {
if (!started) {
r.receiver = null;
r.curApp = null;
prr.removeCurReceiver(r);
}
}
}
//这里的info是通过Resolver解析出来的,存储了BroadcastReceiver信息
//sync顺序与无序==同步与异步
public final void scheduleReceiver(Intent intent, ActivityInfo info,
CompatibilityInfo compatInfo, int resultCode, String data, Bundle extras,
boolean sync, int sendingUser, int processState) {
updateProcessState(processState, false);
ReceiverData r = new ReceiverData(intent, resultCode, data, extras,
sync, false, mAppThread.asBinder(), sendingUser);
r.info = info;
r.compatInfo = compatInfo;
sendMessage(H.RECEIVER, r);
}
private void handleReceiver(ReceiverData data) {
...
String component = data.intent.getComponent().getClassName();
LoadedApk packageInfo = getPackageInfoNoCheck(
data.info.applicationInfo, data.compatInfo);
IActivityManager mgr = ActivityManager.getService();
Application app;
BroadcastReceiver receiver;
ContextImpl context;
try {
app = packageInfo.makeApplication(false, mInstrumentation);
context = (ContextImpl) app.getBaseContext();
if (data.info.splitName != null) {
context = (ContextImpl) context.createContextForSplit(data.info.splitName);
}
if (data.info.attributionTags != null && data.info.attributionTags.length > 0) {
final String attributionTag = data.info.attributionTags[0];
context = (ContextImpl) context.createAttributionContext(attributionTag);
}
//类加载机制所必须的信息
java.lang.ClassLoader cl = context.getClassLoader();
data.intent.setExtrasClassLoader(cl);
data.intent.prepareToEnterProcess(
isProtectedComponent(data.info) || isProtectedBroadcast(data.intent),
context.getAttributionSource());
data.setExtrasClassLoader(cl);
//通过类加载机制创建我们的BroadcastReceiver对象,packageInfo.getAppFactory返回AppComponentFactory对象
receiver = packageInfo.getAppFactory()
.instantiateReceiver(cl, data.info.name, data.intent);
} catch (Exception e) {
data.sendFinished(mgr);
}
try {
//线程内的全局单例,应该在某个地方会读取判断
sCurrentBroadcastIntent.set(data.intent);
//设置处理结果
receiver.setPendingResult(data);
//回调我们自定义的onReceive方法。
receiver.onReceive(context.getReceiverRestrictedContext(),
data.intent);
} catch (Exception e) {
data.sendFinished(mgr);
} finally {
sCurrentBroadcastIntent.set(null);
}
//前面默认设置了data,所以默认情况接收处理,如果不想广播结束,再次调用setResult
if (receiver.getPendingResult() != null) {
data.finish();
}
}
//AppComponentFactory
public @NonNull BroadcastReceiver instantiateReceiver(@NonNull ClassLoader cl,
@NonNull String className, @Nullable Intent intent)
throws InstantiationException, IllegalAccessException, ClassNotFoundException {
return (BroadcastReceiver) cl.loadClass(className).newInstance();
}
//PendingRsult
public final void finish() {
if (mType == TYPE_COMPONENT) {//ReceiverData创建时,被设置为TYPE_COMPONENT,Args创建时TYPE_REGISTERED
final IActivityManager mgr = ActivityManager.getService();
//QueuedWork用于跟踪应用全局的工作是否结束
if (QueuedWork.hasPendingWork()) {
QueuedWork.queue(new Runnable() {
@Override public void run() {
sendFinished(mgr);
}
}, false);
} else {
sendFinished(mgr);
}
} else if (mOrderedHint && mType != TYPE_UNREGISTERED) {//mOrderedHint为true表示顺序广播,TYPE_UNREGISTERED表示当前结注册
final IActivityManager mgr = ActivityManager.getService();
sendFinished(mgr);
}
}
public void sendFinished(IActivityManager am) {
synchronized (this) {
if (mFinished) {
throw new IllegalStateException("Broadcast already finished");
}
mFinished = true;
try {
if (mResultExtras != null) {
mResultExtras.setAllowFds(false);
}
if (mOrderedHint) {//有序
am.finishReceiver(mToken, mResultCode, mResultData, mResultExtras,
mAbortBroadcast, mFlags);
} else {//无序
am.finishReceiver(mToken, 0, null, null, false, mFlags);
}
} catch (RemoteException ex) {
}
}
}
public void finishReceiver(IBinder who, int resultCode, String resultData,
Bundle resultExtras, boolean resultAbort, int flags) {
// Refuse possible leaked file descriptors
if (resultExtras != null && resultExtras.hasFileDescriptors()) {
throw new IllegalArgumentException("File descriptors passed in Bundle");
}
final long origId = Binder.clearCallingIdentity();
try {
boolean doNext = false;
BroadcastRecord r;
BroadcastQueue queue;
synchronized(this) {
//根据Intent的Flags获取广播队列
if (isOnOffloadQueue(flags)) {
queue = mOffloadBroadcastQueue;
} else {
queue = (flags & Intent.FLAG_RECEIVER_FOREGROUND) != 0
? mFgBroadcastQueue : mBgBroadcastQueue;
}
//获取当前正在处理的广播,也就是现在接收者对应的广播
r = queue.getMatchingOrderedReceiver(who);
if (r != null) {
doNext = r.queue.finishReceiverLocked(r, resultCode,
resultData, resultExtras, resultAbort, true);
}
if (doNext) {//如果有,执行下一个广播。参考=>广播队列对广播的处理小节
r.queue.processNextBroadcastLocked(/*fromMsg=*/ false, /*skipOomAdj=*/ true);
}
// updateOomAdjLocked() will be done here
trimApplicationsLocked(false, OomAdjuster.OOM_ADJ_REASON_FINISH_RECEIVER);
}
} finally {
Binder.restoreCallingIdentity(origId);
}
}
public boolean finishReceiverLocked(BroadcastRecord r, int resultCode,
String resultData, Bundle resultExtras, boolean resultAbort, boolean waitForServices) {
final int state = r.state;
final ActivityInfo receiver = r.curReceiver;
final long finishTime = SystemClock.uptimeMillis();
final long elapsed = finishTime - r.receiverTime;
r.state = BroadcastRecord.IDLE;
if (r.allowBackgroundActivityStarts && r.curApp != null) {
if (elapsed > mConstants.ALLOW_BG_ACTIVITY_START_TIMEOUT) {
//执行时间超过允许后台Activity启动时间,则没有启动,移除token即可
r.curApp.removeAllowBackgroundActivityStartsToken(r);
} else {
//赋予更多的时间用来启动后台Activity
postActivityStartTokenRemoval(r.curApp, r);
}
}
//记录执行时间
if (r.nextReceiver > 0) {
r.duration[r.nextReceiver - 1] = elapsed;
}
// 广播在当前程序执行缓慢,非核心系统app下次处理广播时启动延迟策略
//timeoutExempt为true表示不受超时影响,默认为false
if (!r.timeoutExempt) {
if (r.curApp != null
&& mConstants.SLOW_TIME > 0 && elapsed > mConstants.SLOW_TIME) {
if (!UserHandle.isCore(r.curApp.uid)) {
//将进程添加到缓慢列表中
mDispatcher.startDeferring(r.curApp.uid);
}
}
}
//当前广播的清场工作
r.receiver = null;
r.intent.setComponent(null);
if (r.curApp != null && r.curApp.mReceivers.hasCurReceiver(r)) {
r.curApp.mReceivers.removeCurReceiver(r);
mService.enqueueOomAdjTargetLocked(r.curApp);
}
if (r.curFilter != null) {
r.curFilter.receiverList.curBroadcast = null;
}
r.curFilter = null;
r.curReceiver = null;
r.curApp = null;
mPendingBroadcast = null;
r.resultCode = resultCode;
r.resultData = resultData;
r.resultExtras = resultExtras;
if ( && (r.intent.getFlags()&Intent.FLAG_RECEIVER_NO_ABORT) == 0) {
r.resultAbort = resultAbort;
} else {
r.resultAbort = false;
}
// 其他接收者正在等待当前接收者处理完
if (waitForServices && r.curComponent != null && r.queue.mDelayBehindServices
&& r.queue.mDispatcher.getActiveBroadcastLocked() == r) {
ActivityInfo nextReceiver;
if (r.nextReceiver < r.receivers.size()) {
Object obj = r.receivers.get(r.nextReceiver);
nextReceiver = (obj instanceof ActivityInfo) ? (ActivityInfo)obj : null;
} else {
nextReceiver = null;
}
//相同进程的receiver不会执行到此处
if (receiver == null || nextReceiver == null
|| receiver.applicationInfo.uid != nextReceiver.applicationInfo.uid
|| !receiver.processName.equals(nextReceiver.processName)) {
//有后台服务,表示当前正在切换不同的程序的receiver来处理当前broadcast
if (mService.mServices.hasBackgroundServicesLocked(r.userId)) {
r.state = BroadcastRecord.WAITING_SERVICES;
return false;
}
}
}
r.curComponent = null;
// We will process the next receiver right now if this is finishing
// an app receiver (which is always asynchronous) or after we have
// come back from calling a receiver.
return state == BroadcastRecord.APP_RECEIVE
|| state == BroadcastRecord.CALL_DONE_RECEIVE;
}
最后推荐一下我做的网站,玩Android: wanandroid.com ,包含详尽的知识体系、好用的工具,还有本公众号文章合集,欢迎体验和收藏!
推荐阅读:
扫一扫 关注我的公众号
如果你想要跟大家分享你的文章,欢迎投稿~
┏(^0^)┛明天见!