而对有序广播来说,==原则上每次processNextBroadcast()只会将BroadcastRecord发送给一个receiver而已。当然,此时摘下的receiver既有可能是动态注册的,也有可能是静态的==。
对于动态注册的receiver,目标进程处理完广播之后,会间接调用am.finishReceiver()向AMS发出反馈,关于这一步,前文在讲Args.run()时已有涉及,只是当时主要关心的是里面的receiver.onReceive()一句,现在我们要关心其中的receiver.setPendingResult()一句:
不论任何广播,在APK处理完后,都要通知到AMS做一些收尾工作.
参考BroadcastQueue如何分发广播(四)
重点是,有序广播是如何循环起来的?
回顾 Ams中创建BroadcastRecord的代码,mReceivers集合中是有两种对象:ResolveInfo/BroadcastFilter
if (nextReceiver instanceof BroadcastFilter) {
// Simple case: this is a registered receiver who gets
// a direct call.
BroadcastFilter filter = (BroadcastFilter)nextReceiver;
deliverToRegisteredReceiverLocked(r, filter, r.ordered, recIdx);
if (r.receiver == null || !r.ordered) {
// The receiver has already finished, so schedule to
// process the next one.
r.state = BroadcastRecord.IDLE;
scheduleBroadcastsLocked();
} else {
if (brOptions != null && brOptions.getTemporaryAppWhitelistDuration() > 0) {
scheduleTempWhitelistLocked(filter.owningUid,
brOptions.getTemporaryAppWhitelistDuration(), r);
}
}
return;
}
NOTE:
执行流程类似于平行广播,最终也会进入到LoadedApk.ReceiverDispatcher($Args)
区别在于:
deliverToRegisteredReceiverLocked(r, filter, /order/ r.ordered, recIdx) //最终还是会进入到Args.run(){}
try {
ClassLoader cl = mReceiver.getClass().getClassLoader();
intent.setExtrasClassLoader(cl);
intent.prepareToEnterProcess();
setExtrasClassLoader(cl);
// 注意,把自己设到BroadcastReceiver的mPendingResult域里了
receiver.setPendingResult(this);
receiver.onReceive(mContext, intent);
} catch (Exception e) {}
if (receiver.getPendingResult() != null) {
finish();
}
frameworks/base/core / java / android / content /BroadcastReceiver.java
if (mType == TYPE_COMPONENT) {
...
} else if (mOrderedHint && mType != TYPE_UNREGISTERED) {
final IActivityManager mgr = ActivityManagerNative.getDefault();
sendFinished(mgr);
}
public Args(Intent intent, int resultCode, String resultData, Bundle resultExtras,
boolean ordered, boolean sticky, int sendingUser) {
super(resultCode, resultData, resultExtras,
mRegistered ? TYPE_REGISTERED : TYPE_UNREGISTERED,
ordered, sticky, mIIntentReceiver.asBinder(), sendingUser, intent.getFlags());
mCurIntent = intent;
mOrdered = ordered;
}
public void sendFinished(IActivityManager am) {
synchronized (this) {
...
mFinished = true;
try {
// 注册此处的区别,对于ordered广播,需要保留resultCode resultData,resultExtras, mAbortBroadcst等信息,而对于
// 并行广播,无须关注这些
if (mOrderedHint) {
// 将广播结束的消息告知Ams
am.finishReceiver(mToken, mResultCode, mResultData, mResultExtras,
mAbortBroadcast, mFlags);
} else {
// This broadcast was sent to a component; it is not ordered,
// but we still need to tell the activity manager we are done.
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) {
try {
boolean doNext = false;
BroadcastRecord r;
synchronized(this) {
BroadcastQueue queue = (flags & Intent.FLAG_RECEIVER_FOREGROUND) != 0
? mFgBroadcastQueue : mBgBroadcastQueue;
//
r = queue.getMatchingOrderedReceiver(who);
if (r != null) {
// finishReceiverLocked做善后工作,判断该节点是否还需要继续分发
doNext = r.queue.finishReceiverLocked(r, resultCode,
resultData, resultExtras, resultAbort, true);
}
}
//
if (doNext) {
r.queue.processNextBroadcast(false);
}
} finally {
}
}
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;
r.state = BroadcastRecord.IDLE;
// 这里为什么要做大量的置空操作?
r.receiver = null;
r.intent.setComponent(null);
if (r.curApp != null && r.curApp.curReceiver == r) {
r.curApp.curReceiver = null;
}
if (r.curFilter != null) {
r.curFilter.receiverList.curBroadcast = null;
}
r.curFilter = null;
r.curReceiver = null;
r.curApp = null;
mPendingBroadcast = null;
// 保留上个receiver的操作结果
r.resultCode = resultCode;
r.resultData = resultData;
r.resultExtras = resultExtras;
...
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;
}
最后的state 为什么要== APP_RECEIVE/ CALL_DONE_RECEIVE
针对ordered广播在deliver后,都会重置状态,表示该节点的发送状态;当在finish时重置r.state = Idle,以便将此records分发给下一个receiver.
// 对于静态广播的接收是由ActivityThread来分发的
private void handleReceiver(ReceiverData data)
{
. . . . . .
IActivityManager mgr = ActivityManagerNative.getDefault();
BroadcastReceiver receiver;
try {
java.lang.ClassLoader cl = packageInfo.getClassLoader();
data.intent.setExtrasClassLoader(cl);
data.setExtrasClassLoader(cl);
receiver = (BroadcastReceiver)cl.loadClass(component).newInstance();
} catch (Exception e) {
. . . . . .
}
try {
. . . . . .
receiver.setPendingResult(data);
receiver.onReceive(context.getReceiverRestrictedContext(), data.intent);
} catch (Exception e) {
. . . . . .
} finally {
sCurrentBroadcastIntent.set(null);
}
if (receiver.getPendingResult() != null) {
data.finish();
}
}
public ReceiverData(Intent intent, int resultCode, String resultData, Bundle resultExtras,
boolean ordered, boolean sticky, IBinder token, int sendingUser) {
super(resultCode, resultData, resultExtras, TYPE_COMPONENT, ordered, sticky,
token, sendingUser, intent.getFlags());
this.intent = intent;
}
public final void finish() {
if (mType == TYPE_COMPONENT) {
final IActivityManager mgr = ActivityManagerNative.getDefault();
if (QueuedWork.hasPendingWork()) {
...
} else {
sendFinished(mgr);
}
} else if (mOrderedHint && mType != TYPE_UNREGISTERED) {
...
}
}
==至此,静态receiver的完整分发流程结束==
如何将Broadcast完整的发送给所有的receiver
do{
int numReceivers = (r.receivers != null) ? r.receivers.size() : 0;
// nextReceiver > numReceivers,即表示发送到了该节点的最后一条
if (r.receivers == null || r.nextReceiver >= numReceivers
|| r.resultAbort || forceReceive) {
// No more receivers for this broadcast! Send the final
// result if requested...
cancelBroadcastTimeoutLocked();
// 添加到Broadcast 记录
addBroadcastToHistoryLocked(r);
if (r.intent.getComponent() == null && r.intent.getPackage() == null
&& (r.intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
// This was an implicit broadcast... let's record it for posterity.
mService.addBroadcastStatLocked(r.intent.getAction(), r.callerPackage,
r.manifestCount, r.manifestSkipCount, r.finishTime-r.dispatchTime);
}
// 并且需要将这个操作完成的节点,从list中移除
mOrderedBroadcasts.remove(0);
r = null;
looped = true;
continue;
}
} while ( r != null)