android广播动态注册与发送流程分析
1、相关代码
\frameworks\base\core\java\android\app\ContextImpl.java
\frameworks\base\core\java\android\app\LoadedApk.java
\frameworks\base\services\core\java\com\android\server\am\ActivityManagerService.java
\frameworks\base\services\core\java\com\android\server\am\BroadcastQueue.java
\frameworks\base\core\java\android\app\BroadcastOptions.java
\frameworks\base\services\core\java\com\android\server\am\ReceiverList.java
\frameworks\base\services\core\java\com\android\server\IntentResolver.java
\frameworks\base\services\core\java\com\android\server\am\BroadcastFilter.java
2.1广播动态注册流程
简要流程如上图,注册过程主要通过AMS调用,将注册的intentFilter添加到BroadcastFilter中的队列mFilters中,同时将IIntentReceiver对象添加到mRegisteredReceivers中。
public Intent registerReceiver(IApplicationThread caller, String callerPackage,
IIntentReceiver receiver, IntentFilter filter, String permission, int userId,
int flags) {
ArrayList<Intent> stickyIntents = null;
//...... 对调用者,instantApp、flag等做检查
//......处理粘性广播,将粘性广播加到粘性广播队列中
synchronized (this) {
//从现有队列中查找本地的IIntentReceiver
ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
if (rl == null) {
//如果当前没有,则新建,并且每个应用只能创建1000个receiver超过会报异常
rl = new ReceiverList(this, callerApp, callingPid, callingUid,
userId, receiver);
//......
mRegisteredReceivers.put(receiver.asBinder(), rl);
} else if (rl.uid != callingUid) {
//跟已有uid不同报异常
} else if (rl.pid != callingPid) {
//跟已有pid不同报异常
} else if (rl.userId != userId) {
//跟已有userId不同报异常
}
BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
permission, callingUid, userId, instantApp, visibleToInstantApps);
if (rl.containsFilter(filter)) {
//intentfilter已存在,不再重复添加
} else {
rl.add(bf);
//添加intentFilter到mReceiverResolver表中
mReceiverResolver.addFilter(bf);
}
if (allSticky != null) {
//发送粘性广播
for (int i = 0; i < stickyCount; i++) {
Intent intent = allSticky.get(i);
BroadcastQueue queue = broadcastQueueForIntent(intent);
BroadcastRecord r = new BroadcastRecord(queue, intent, null,
null, -1, -1, false, null, null, OP_NONE, null, receivers,
null, 0, null, null, false, true, true, -1);
queue.enqueueParallelBroadcastLocked(r);
queue.scheduleBroadcastsLocked();
}
}
//......
}
}
注册过程主要涉及两个重要标量:
final HashMap<IBinder, ReceiverList> mRegisteredReceivers = new HashMap<>();
final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
= new IntentResolver<BroadcastFilter, BroadcastFilter>() {
//......
};
final class ReceiverList extends ArrayList<BroadcastFilter>
implements IBinder.DeathRecipient {
final ActivityManagerService owner;
public final IIntentReceiver receiver;
public final ProcessRecord app;
public final int pid;
public final int uid;
public final int userId;
BroadcastRecord curBroadcast = null;
boolean linkedToDeath = false;
final class BroadcastFilter extends IntentFilter {
// Back-pointer to the list this filter is in.
final ReceiverList receiverList;
final String packageName;
final String requiredPermission;
final int owningUid;
final int owningUserId;
final boolean instantApp;
final boolean visibleToInstantApp;
ReceiverList类相当于我们代码中的具体receiver,BroadcastFilter则相当于我们在注册广播时候施使用的intentFilter,一个进程不能注册超过1000个receiver,每个receiver中可以有多个BroadcastFilte,每次注册时候,先查找该receiver是否已经存在于当前的mRegisteredReceivers列表中了,如果已经存在,则检查这次注册者的pid、uid、userId是否跟已经存在的receiver中的这三个值相同,不同则抛出异常。
然后根据现有的或者新生成的ReceiverList名称rl,生成BroadcastFilter,如果该rl中已经包含给intentFilter,表示该已经存在了相同的receiver,包含了相同的intentfilter,不用再重复注册了,如果不包含,则将新生成的BroadcastFilter加入到rl中,将新建的BroadcastFilter加入到mReceiverResolver中。
解除注册,最重要的就是从这两个表中移出对象:
void removeReceiverLocked(ReceiverList rl) {
mRegisteredReceivers.remove(rl.receiver.asBinder());
for (int i = rl.size() - 1; i >= 0; i--) {
mReceiverResolver.removeFilter(rl.get(i));
}
}
2.2 广播发送流程
广播发送简略流程如上图所示,在进行了一些列的检查,包括参数,调用者,广播flag,特殊action,系统广播,等之后,从mReceiverResolver中检索出广播接收者,然后按照优先无序广播,之后发送有序广播的顺序,依次调用所有接收者的IIntentReceiver中的onReceive中。
两个广播发送序列,前台序列、后台序列
BroadcastQueue mFgBroadcastQueue;
BroadcastQueue mBgBroadcastQueue;
public final int broadcastIntent(IApplicationThread caller,
Intent intent, String resolvedType, IIntentReceiver resultTo,
int resultCode, String resultData, Bundle resultExtras,
String[] requiredPermissions, int appOp, Bundle bOptions,
boolean serialized, boolean sticky, int userId) {
enforceNotIsolatedCaller("broadcastIntent");
synchronized(this) {
intent = verifyBroadcastLocked(intent);
final ProcessRecord callerApp = getRecordForAppLocked(caller);
final int callingPid = Binder.getCallingPid();
final int callingUid = Binder.getCallingUid();
final long origId = Binder.clearCallingIdentity();
int res = broadcastIntentLocked(callerApp,
callerApp != null ? callerApp.info.packageName : null,
intent, resolvedType, resultTo, resultCode, resultData, resultExtras,
requiredPermissions, appOp, bOptions, serialized, sticky,
callingPid, callingUid, userId);
Binder.restoreCallingIdentity(origId);
return res;
}
}
final int broadcastIntentLocked(ProcessRecord callerApp,
String callerPackage, 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 userId) {
//......flag 相关处理
if (callerInstantApp) {
intent.setFlags(intent.getFlags() & ~Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS);
}
intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
if (!mProcessesReady && (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
}
//......保护广播检测,非系统应用发送保护广播会报错
isProtectedBroadcast = AppGlobals.getPackageManager().isProtectedBroadcast(action);
if (!isCallerSystem) {
if (isProtectedBroadcast) {
String msg = "Permission Denial: not allowed to send broadcast "
+ action + " from pid="
+ callingPid + ", uid=" + callingUid;
Slog.w(TAG, msg);
throw new SecurityException(msg);
//......
}
//......处理特殊action,如:ACTION_UID_REMOVED,ACTION_PACKAGES_UNSUSPENDED,ACTION_PACKAGE_REPLACED等
//如果发送的是粘性广播
if (sticky) {
//检查android.Manifest.permission.BROADCAST_STICKY权限,没有则抛出异常
if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
callingPid, callingUid)
!= PackageManager.PERMISSION_GRANTED) {
String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
+ callingPid + ", uid=" + callingUid
+ " requires " + android.Manifest.permission.BROADCAST_STICKY;
Slog.w(TAG, msg);
throw new SecurityException(msg);
}
//强制粘性广播必须带权限发送,否则直接返回
if (requiredPermissions != null && requiredPermissions.length > 0) {
Slog.w(TAG, "Can't broadcast sticky intent " + intent
+ " and enforce permissions " + Arrays.toString(requiredPermissions));
return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
}
//强制粘性广播不允许指定接收组件,否则抛出异常
if (intent.getComponent() != null) {
throw new SecurityException(
"Sticky broadcasts can't target a specific component");
}
//检查发送用户组
//......
for (i = 0; i < stickiesCount; i++) {
if (intent.filterEquals(list.get(i))) {
// 该粘性广播已经存在,直接替换
list.set(i, new Intent(intent));
break;
}
}
if (i >= stickiesCount) {
//不存在,则添加到队列中
list.add(new Intent(intent));
}
}
//一下两个列表用于装载广播接收者
List receivers = null;
List<BroadcastFilter> registeredReceivers = null;
//......
//检索广播接收对象
registeredReceivers = mReceiverResolver.queryIntent(intent,
resolvedType, false /*defaultOnly*/, userId);
//优先发送无序广播 ,ordered为false表示无序
int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
if (!ordered && NR > 0) {
final BroadcastQueue queue = broadcastQueueForIntent(intent);
BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
callerPackage, callingPid, callingUid, callerInstantApp, resolvedType,
requiredPermissions, appOp, brOptions, registeredReceivers, resultTo,
resultCode, resultData, resultExtras, ordered, sticky, false, userId);
// ......
if (!replaced) {
//发送广播
queue.enqueueParallelBroadcastLocked(r);
queue.scheduleBroadcastsLocked();
}
registeredReceivers = null;
NR = 0;
}
//......发送有序广播
BroadcastQueue queue = broadcastQueueForIntent(intent);
BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
callerPackage, callingPid, callingUid, callerInstantApp, resolvedType,
requiredPermissions, appOp, brOptions, receivers, resultTo, resultCode,
resultData, resultExtras, ordered, sticky, false, userId);
queue.enqueueOrderedBroadcastLocked(r);
queue.scheduleBroadcastsLocked();
}
BroadcastQueue中两个列表,无序广播队列、有序广播队列。
final ArrayList<BroadcastRecord> mParallelBroadcasts = new ArrayList<>();
final ArrayList<BroadcastRecord> mOrderedBroadcasts = new ArrayList<>();
如以上分析,分别将有序广播和无序广播加入到不同的两个队列中。
public void enqueueParallelBroadcastLocked(BroadcastRecord r) {
mParallelBroadcasts.add(r);
enqueueBroadcastHelper(r);
}
public void enqueueOrderedBroadcastLocked(BroadcastRecord r) {
mOrderedBroadcasts.add(r);
enqueueBroadcastHelper(r);
}
发送消息进入广播发送流程
public void scheduleBroadcastsLocked() {
if (mBroadcastsScheduled) {
return;
}
mHandler.sendMessage(mHandler.obtainMessage(BROADCAST_INTENT_MSG, this));
mBroadcastsScheduled = true;
}
广播在同步方法块中进行
final void processNextBroadcast(boolean fromMsg) {
synchronized (mService) {
processNextBroadcastLocked(fromMsg, false);
}
}
processNextBroadcastLocked方法详细流程如下:
final void processNextBroadcastLocked(boolean fromMsg, boolean skipOomAdj) {
BroadcastRecord r;
if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "processNextBroadcast ["
+ mQueueName + "]: "
+ mParallelBroadcasts.size() + " parallel broadcasts, "
+ mOrderedBroadcasts.size() + " ordered broadcasts");
mService.updateCpuStats();
if (fromMsg) {
mBroadcastsScheduled = false;
}
// 先将无序广播发送掉
while (mParallelBroadcasts.size() > 0) {
r = mParallelBroadcasts.remove(0);
r.dispatchTime = SystemClock.uptimeMillis();
r.dispatchClockTime = System.currentTimeMillis();
......
final int N = r.receivers.size();
......
for (int i=0; i<N; i++) {
Object target = r.receivers.get(i);
//......在循环中完成所有接收者的回调,完成广播发送
deliverToRegisteredReceiverLocked(r, (BroadcastFilter)target, false, i);
}
addBroadcastToHistoryLocked(r);
......
}
// Now take care of the next serialized one...
// 如果我们正在等待一个进程起来处理下一个广播,在这个点我们什么也不做,
//防止万一,我们检查我们等待的进程是否依然存在
if (mPendingBroadcast != null) {
......
boolean isDead;
if (mPendingBroadcast.curApp.pid > 0) {
synchronized (mService.mPidsSelfLocked) {
ProcessRecord proc = mService.mPidsSelfLocked.get(
mPendingBroadcast.curApp.pid);
isDead = proc == null || proc.crashing;
}
} else {
final ProcessRecord proc = mService.mProcessNames.get(
mPendingBroadcast.curApp.processName, mPendingBroadcast.curApp.uid);
isDead = proc == null || !proc.pendingStart;
}
if (!isDead) {
//此处无法理为什么进程存在的时候要返回
return;
} else {
......
mPendingBroadcast.state = BroadcastRecord.IDLE;
mPendingBroadcast.nextReceiver = mPendingBroadcastRecvIndex;
mPendingBroadcast = null;
}
}
boolean looped = false;
do {
......
//从有序广播队列中获取接收队列
r = mOrderedBroadcasts.get(0);
int numReceivers = (r.receivers != null) ? r.receivers.size() : 0;
if (mService.mProcessesReady && r.dispatchTime > 0) {
long now = SystemClock.uptimeMillis();
//如果现在距离dispatch时候的时间超过了mTimeoutPeriod的两倍,则进入超时ANR异常
//mTimeoutPeriod定义:前天广播10秒,后台广播60秒
if ((numReceivers > 0) &&
(now > r.dispatchTime + (2*mTimeoutPeriod*numReceivers))) {
broadcastTimeoutLocked(false);
forceReceive = true;
r.state = BroadcastRecord.IDLE;
}
}
......
return;
}
if (r.receivers == null || r.nextReceiver >= numReceivers
|| r.resultAbort || forceReceive) {
if (r.resultTo != null) {
try {
//通知到接收者的onrecevier中
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) {
}
}
......
mOrderedBroadcasts.remove(0);
r = null;
looped = true;
continue;
}
} while (r == null);
// 得到下一个 receiver...
int recIdx = r.nextReceiver++;
// Keep track of when this receiver started, and make sure there
// is a timeout message pending to kill it if need be.
r.receiverTime = SystemClock.uptimeMillis();
if (recIdx == 0) {
r.dispatchTime = r.receiverTime;
r.dispatchClockTime = System.currentTimeMillis();
......
}
if (! mPendingBroadcastTimeoutMessage) {
long timeoutTime = r.receiverTime + mTimeoutPeriod;
//设置发送超时
setBroadcastTimeoutLocked(timeoutTime);
}
final BroadcastOptions brOptions = r.options;
final Object nextReceiver = r.receivers.get(recIdx);
if (nextReceiver instanceof BroadcastFilter) {
BroadcastFilter filter = (BroadcastFilter)nextReceiver;
//发送广播
deliverToRegisteredReceiverLocked(r, filter, r.ordered, recIdx);
if (r.receiver == null || !r.ordered) {
//进入递归调用启动发送广播
scheduleBroadcastsLocked();
} else {
if (brOptions != null && brOptions.getTemporaryAppWhitelistDuration() > 0) {
scheduleTempWhitelistLocked(filter.owningUid,
brOptions.getTemporaryAppWhitelistDuration(), r);
}
}
return;
}
//难点:需要实例化接收者,可能需要启动他们的应用用来支持这个receiver
ResolveInfo info =
(ResolveInfo)nextReceiver;
ComponentName component = new ComponentName(
info.activityInfo.applicationInfo.packageName,
info.activityInfo.name);
boolean skip = false;
//brOptions非空,并且当前targetSdkVersion小于option设置的最小值或者大于最大值,skip就为true,直接跳过
if (brOptions != null &&
(info.activityInfo.applicationInfo.targetSdkVersion
< brOptions.getMinManifestReceiverApiLevel() ||
info.activityInfo.applicationInfo.targetSdkVersion
> brOptions.getMaxManifestReceiverApiLevel())) {
skip = true;
}
//得到授权信息,系统或者root进程直接返回granted
int perm = mService.checkComponentPermission(info.activityInfo.permission,
r.callingPid, r.callingUid, info.activityInfo.applicationInfo.uid,
info.activityInfo.exported);
if (!skip && perm != PackageManager.PERMISSION_GRANTED) {
//不跳过,但是权限不允许,则skip置为true
skip = true;
} else if (!skip && info.activityInfo.permission != null) {
final int opCode = AppOpsManager.permissionToOpCode(info.activityInfo.permission);
if (opCode != AppOpsManager.OP_NONE
&& mService.mAppOpsService.noteOperation(opCode, r.callingUid,
r.callerPackage) != AppOpsManager.MODE_ALLOWED) {
//......permission不为空,并且appops授权检查未通过
skip = true;
}
}
if (!skip && info.activityInfo.applicationInfo.uid != Process.SYSTEM_UID &&
r.requiredPermissions != null && r.requiredPermissions.length > 0) {
for (int i = 0; i < r.requiredPermissions.length; i++) {
String requiredPermission = r.requiredPermissions[i];
try {
perm = AppGlobals.getPackageManager().
checkPermission(requiredPermission,
info.activityInfo.applicationInfo.packageName,
UserHandle
.getUserId(info.activityInfo.applicationInfo.uid));
} catch (RemoteException e) {
perm = PackageManager.PERMISSION_DENIED;
}
if (perm != PackageManager.PERMISSION_GRANTED) {
//uid不等于SYSTEM_UID,requiredPermissions不为空,并且PMS未授权
skip = true;
break;
}
int appOp = AppOpsManager.permissionToOpCode(requiredPermission);
if (appOp != AppOpsManager.OP_NONE && appOp != r.appOp
&& mService.mAppOpsService.noteOperation(appOp,
info.activityInfo.applicationInfo.uid, info.activityInfo.packageName)
!= AppOpsManager.MODE_ALLOWED) {
//uid不等于SYSTEM_UID,requiredPermissions不为空,并且APPOPS未授权
skip = true;
break;
}
}
}
if (!skip && r.appOp != AppOpsManager.OP_NONE
&& mService.mAppOpsService.noteOperation(r.appOp,
info.activityInfo.applicationInfo.uid, info.activityInfo.packageName)
!= AppOpsManager.MODE_ALLOWED) {
//appOp非空,并且appops权限检查未授予
skip = true;
}
if (!skip) {
//检测该intent是否阻塞
skip = !mService.mIntentFirewall.checkBroadcast(r.intent, r.callingUid,
r.callingPid, r.resolvedType, info.activityInfo.applicationInfo.uid);
}
boolean isSingleton = false;
try {
isSingleton = mService.isSingleton(info.activityInfo.processName,
info.activityInfo.applicationInfo,
info.activityInfo.name, info.activityInfo.flags);
} catch (SecurityException e) {
Slog.w(TAG, e.getMessage());
skip = true;
}
if ((info.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
if (ActivityManager.checkUidPermission(
android.Manifest.permission.INTERACT_ACROSS_USERS,
info.activityInfo.applicationInfo.uid)
!= PackageManager.PERMISSION_GRANTED) {
//设置了activityInfo.flags,FLAG_SINGLE_USER,但没有INTERACT_ACROSS_USERS权限
skip = true;
}
}
if (!skip && info.activityInfo.applicationInfo.isInstantApp()
&& r.callingUid != info.activityInfo.applicationInfo.uid) {
//isInstantApp跳过
skip = true;
}
if (!skip && r.callerInstantApp
&& (info.activityInfo.flags & ActivityInfo.FLAG_VISIBLE_TO_INSTANT_APP) == 0
&& r.callingUid != info.activityInfo.applicationInfo.uid) {
//callerInstantApp,并且设置了FLAG_VISIBLE_TO_INSTANT_APP
skip = true;
}
if (r.curApp != null && r.curApp.crashing) {
// 进程正在报错,跳过
skip = true;
}
if (!skip) {
boolean isAvailable = false;
try {
isAvailable = AppGlobals.getPackageManager().isPackageAvailable(
info.activityInfo.packageName,
UserHandle.getUserId(info.activityInfo.applicationInfo.uid));
} catch (Exception e) {
}
if (!isAvailable) {
//应用当前不可用 ,依然跳过
skip = true;
}
}
//如果组件权限需要review才能运行,跳过该广播,如果应用在前台,则启动review界面传递该intent
if (mService.mPermissionReviewRequired && !skip) {
if (!requestStartTargetPermissionsReviewIfNeededLocked(r,
info.activityInfo.packageName, UserHandle.getUserId(
info.activityInfo.applicationInfo.uid))) {
skip = true;
}
}
......
String targetProcess = info.activityInfo.processName;
ProcessRecord app = mService.getProcessRecordLocked(targetProcess,
info.activityInfo.applicationInfo.uid, false);
if (!skip) {
final int allowed = mService.getAppStartModeLocked(
info.activityInfo.applicationInfo.uid, info.activityInfo.packageName,
info.activityInfo.applicationInfo.targetSdkVersion, -1, true, false, false);
if (allowed != ActivityManager.APP_START_MODE_NORMAL) {
if (allowed == ActivityManager.APP_START_MODE_DISABLED) {
//startMode是APP_START_MODE_DISABLED的时候跳过
skip = true;
} else if (((r.intent.getFlags()&Intent.FLAG_RECEIVER_EXCLUDE_BACKGROUND) != 0)
|| (r.intent.getComponent() == null
&& r.intent.getPackage() == null
&& ((r.intent.getFlags()
& Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND) == 0)
&& !isSignaturePerm(r.requiredPermissions))) {
mService.addBackgroundCheckViolationLocked(r.intent.getAction(),
component.getPackageName());
//设置了FLAG_RECEIVER_EXCLUDE_BACKGROUND 或者 (component为空,并且package为空,并且
//设置了FLAG_RECEIVER_INCLUDE_BACKGROUND 并且requiredPermissions都是签名权限) 则跳过,不允许
skip = true;
}
}
}
if (!skip && !Intent.ACTION_SHUTDOWN.equals(r.intent.getAction())
&& !mService.mUserController
.isUserRunning(UserHandle.getUserId(info.activityInfo.applicationInfo.uid),
0 /* flags */)) {
skip = true;
//用户已经停止运行,跳过
}
if (skip) {
if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST,
"Skipping delivery of ordered [" + mQueueName + "] "
+ r + " for whatever reason");
r.delivery[recIdx] = BroadcastRecord.DELIVERY_SKIPPED;
r.receiver = null;
r.curFilter = null;
r.state = BroadcastRecord.IDLE;
r.manifestSkipCount++;
//递归调用发送广播流程
scheduleBroadcastsLocked();
return;
}
r.manifestCount++;
r.delivery[recIdx] = BroadcastRecord.DELIVERY_DELIVERED;
r.state = BroadcastRecord.APP_RECEIVE;
r.curComponent = component;
r.curReceiver = info.activityInfo;
if (brOptions != null && brOptions.getTemporaryAppWhitelistDuration() > 0) {
scheduleTempWhitelistLocked(receiverUid,
brOptions.getTemporaryAppWhitelistDuration(), r);
}
// 广播正在执行,包无法停止.
try {
AppGlobals.getPackageManager().setPackageStoppedState(
r.curComponent.getPackageName(), false, UserHandle.getUserId(r.callingUid));
} catch (RemoteException e) {
} catch (IllegalArgumentException e) {
}
// 接收进程正在运行
if (app != null && app.thread != null && !app.killed) {
try {
app.addPackage(info.activityInfo.packageName,
info.activityInfo.applicationInfo.versionCode, mService.mProcessStats);
//调用app.thread.scheduleReceiver后返回
processCurBroadcastLocked(r, app, skipOomAdj);
return;
} catch (RemoteException e) {
} catch (RuntimeException e) {
//如果发生了预料之外的异常,则跳过这次广播,重新开发下次广播发送,
//这里现在是在系统进程中
logBroadcastReceiverDiscardLocked(r);
finishReceiverLocked(r, r.resultCode, r.resultData,
r.resultExtras, r.resultAbort, false);
scheduleBroadcastsLocked();
// We need to reset the state if we failed to start the receiver.
r.state = BroadcastRecord.IDLE;
return;
}
}
//未在运行,则调用startProcessLocked启动该进程,用来接收广播
if ((r.curApp=mService.startProcessLocked(targetProcess,
info.activityInfo.applicationInfo, true,
r.intent.getFlags() | Intent.FLAG_FROM_BACKGROUND,
"broadcast", r.curComponent,
(r.intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0, false, false))
== null) {
//进程启动过程发生异常,结束本次广播,继续下个广播
logBroadcastReceiverDiscardLocked(r);
finishReceiverLocked(r, r.resultCode, r.resultData,
r.resultExtras, r.resultAbort, false);
scheduleBroadcastsLocked();
r.state = BroadcastRecord.IDLE;
return;
}
mPendingBroadcast = r;
mPendingBroadcastRecvIndex = recIdx;
}
deliverToRegisteredReceiverLocked方法流程分析:
private void deliverToRegisteredReceiverLocked(BroadcastRecord r,
BroadcastFilter filter, boolean ordered, int index) {
boolean skip = false;
if (filter.requiredPermission != null) {
int perm = mService.checkComponentPermission(filter.requiredPermission,
r.callingPid, r.callingUid, -1, true);
if (perm != PackageManager.PERMISSION_GRANTED) {
// BroadcastFilter所带权限不允许,跳过
skip = true;
} else {
final int opCode = AppOpsManager.permissionToOpCode(filter.requiredPermission);
if (opCode != AppOpsManager.OP_NONE
&& mService.mAppOpsService.noteOperation(opCode, r.callingUid,
r.callerPackage) != AppOpsManager.MODE_ALLOWED) {
// BroadcastFilter所带权限appops检测不允许,跳过
skip = true;
}
}
}
//检查BroadcastRecord的requiredPermission是否通过PMS和APPOPS授权,若未授权,则跳过
if (!skip && (filter.receiverList.app == null || filter.receiverList.app.killed
|| filter.receiverList.app.crashing)) {
//crash 进程跳过
skip = true;
}
......
if (!skip && !visibleToInstantApps && filter.instantApp
&& filter.receiverList.uid != r.callingUid) {
//instantApp 跳过
skip = true;
}
if (!skip && !filter.visibleToInstantApp && r.callerInstantApp
&& filter.receiverList.uid != r.callingUid) {
skip = true;
}
//跳过该广播发送
if (skip) {
r.delivery[index] = BroadcastRecord.DELIVERY_SKIPPED;
return;
}
......
try {
// ......发送广播
performReceiveLocked(filter.receiverList.app, filter.receiverList.receiver,
new Intent(r.intent), r.resultCode, r.resultData,
r.resultExtras, r.ordered, r.initialSticky, r.userId);
......
} catch (RemoteException e) {
......
}
}
void performReceiveLocked(ProcessRecord app, IIntentReceiver receiver,
Intent intent, int resultCode, String data, Bundle extras,
boolean ordered, boolean sticky, int sendingUser) throws RemoteException {
// Send the intent to the receiver asynchronously using one-way binder calls.
if (app != null) {
if (app.thread != null) {
//app 与 thread 不为空,则直接调用scheduleRegisteredReceiver,回调进广播线程
try {
app.thread.scheduleRegisteredReceiver(receiver, intent, resultCode,
data, extras, ordered, sticky, sendingUser, app.repProcState);
} catch (RemoteException ex) {
// Failed to call into the process. It's either dying or wedged. Kill it gently.
synchronized (mService) {
Slog.w(TAG, "Can't deliver broadcast to " + app.processName
+ " (pid " + app.pid + "). Crashing it.");
app.scheduleCrash("can't deliver broadcast");
}
throw ex;
}
} else {
// Application has died. Receiver doesn't exist.
throw new RemoteException("app.thread must not be null");
}
} else {
receiver.performReceive(intent, resultCode, data, extras, ordered,
sticky, sendingUser);
}
}
通过binder远程调用,回到ApplicationThread中,
private class ApplicationThread extends IApplicationThread.Stub {
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中流程如下:
static final class ReceiverDispatcher {
final static class InnerReceiver extends IIntentReceiver.Stub {
final WeakReference<LoadedApk.ReceiverDispatcher> mDispatcher;
final LoadedApk.ReceiverDispatcher mStrongRef;
InnerReceiver(LoadedApk.ReceiverDispatcher rd, boolean strong) {
mDispatcher = new WeakReference<LoadedApk.ReceiverDispatcher>(rd);
mStrongRef = strong ? rd : null;
}
@Override
public void performReceive(Intent intent, int resultCode, String data,
Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
......
if (rd != null) {
rd.performReceive(intent, resultCode, data, extras,
ordered, sticky, sendingUser);
......
}
}
}
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) {
Log.wtf(TAG, "Null intent received");
} else {
if (ActivityThread.DEBUG_BROADCAST) {
int seq = intent.getIntExtra("seq", -1);
Slog.i(ActivityThread.TAG, "Enqueueing broadcast " + intent.getAction()
+ " seq=" + seq + " to " + mReceiver);
}
}
//将该runnable发送到activitythread线程中执行,所以广播的执行是在主线程中,超时会产生ANR
if (intent == null || !mActivityThread.post(args.getRunnable())) {
if (mRegistered && ordered) {
IActivityManager mgr = ActivityManager.getService();
if (ActivityThread.DEBUG_BROADCAST) Slog.i(ActivityThread.TAG,
"Finishing sync broadcast to " + mReceiver);
args.sendFinished(mgr);
}
}
}
Args类中流程如下:
public final Runnable getRunnable() {
return () -> {
final BroadcastReceiver receiver = mReceiver;
final boolean ordered = mOrdered;
......
try {
ClassLoader cl = mReceiver.getClass().getClassLoader();
intent.setExtrasClassLoader(cl);
intent.prepareToEnterProcess();
setExtrasClassLoader(cl);
receiver.setPendingResult(this);
//回调到onReceiver接口
receiver.onReceive(mContext, intent);
} catch (Exception e) {
......
}
......
};
至此,广播的动态注册,和动态发送流程简要分析结束。