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 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 mRegisteredReceivers = new HashMap<>();final IntentResolver mReceiverResolver = new IntentResolver() { //......};
final class ReceiverList extends ArrayList 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 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 mParallelBroadcasts = new ArrayList<>();final ArrayList 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 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 mDispatcher; final LoadedApk.ReceiverDispatcher mStrongRef; InnerReceiver(LoadedApk.ReceiverDispatcher rd, boolean strong) { mDispatcher = new WeakReference(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) { ...... } ...... };
至此,广播的动态注册,和动态发送流程简要分析结束。
更多相关文章
- android 3G pppd 调试记录
- Android面试系列文章2018之Android部分Broadcast篇
- Android面试系列文章2018之Android部分Broadcast篇
- 【Android(安卓)开发】: Android(安卓)消息处理机制之一: Handle
- 【Android(安卓)开发】: Android(安卓)消息处理机制之一: Handle
- Android(安卓)短信发送
- Android(安卓)应用程序请求Vsync
- android 中发送短信
- 【Android】Android(安卓)开机广播的使用