Android广播发送流程(广播3)

本文深入解析了Android系统中广播发送的详细流程,包括广播的发送方式、系统处理过程、广播队列管理及接收者处理逻辑。涉及广播类型如普通、有序、粘性广播及其发送方法,以及AMS如何调度和分发广播给静态与动态注册的接收者。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1. 广播发送流程

这次我们讲一下广播发送的流程,老规矩先上大概的流程图
在这里插入图片描述

2. 广播发送

  1. 常见的通过ContextImpl.java发送广播的方法有下面几种
    => sendBroadcast/sendBroadcastAsUser :普通的广播发送,默认是当前userId,带有“AsUser”的是发送给特定的user
    => sendBroadcastMultiplePermissions/sendBroadcastAsUserMultiplePermissions :带有多个权限的广播发送
    => sendOrderedBroadcast/sendOrderedBroadcastAsUser :发送order有序的广播(order广播是一个接收完成下一个才能接收,接收者一个个按顺序接收)
    => sendStickyBroadcast/sendStickyBroadcastAsUser :发送粘性广播,粘性广播的意思是注册者注册了就马上能收到该类型(之前已经发送的粘性广播)的广播,
    接收者的注册不需要在发送者的前面
    => sendStickyOrderedBroadcast/sendStickyOrderedBroadcastAsUser :发送粘性而且是顺序order的广播

它们都是调用AMS的broadcastIntentWithFeature来发送广播

如下面是最简单的只有一个Intent的广播发送

//ContextImpl.java
    @Override
    public void sendBroadcast(Intent intent) {
        warnIfCallingFromSystemProcess();
        String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
        try {
            intent.prepareToLeaveProcess(this);
            //调用的是AMS的broadcastIntentWithFeature来发送广播
            ActivityManager.getService().broadcastIntentWithFeature(
                    mMainThread.getApplicationThread(), getAttributionTag(), intent, resolvedType,
                    null, Activity.RESULT_OK, null, null, null, null /*excludedPermissions=*/,
                    AppOpsManager.OP_NONE, null, false, false, getUserId());
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
        }
    }
  1. 还是以亮屏SCREEN_ON的广播继续讲解其发送流程
    其调用方法是sendOrderedBroadcastAsUser(ContextImpl.java)->broadcastIntentWithFeature(ActivityManagerService.java)
//Notifier.java
    private final Intent mScreenOnIntent;
	//新建一个Intent,它的action是ACTION_SCREEN_ON,
	//注意此处增加了
	//FLAG_RECEIVER_REGISTERED_ONLY: 只允许动态注册的接收者接受
	//FLAG_RECEIVER_FOREGROUND: 前台接收,也就是前台广播(10s超时)的队列
	//FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS: 可以被即时app接收
	mScreenOnIntent = new Intent(Intent.ACTION_SCREEN_ON);
	mScreenOnIntent.addFlags(
			Intent.FLAG_RECEIVER_REGISTERED_ONLY | Intent.FLAG_RECEIVER_FOREGROUND
			| Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS);

    //亮屏广播发送完成后才调用的
    private final BroadcastReceiver mWakeUpBroadcastDone = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            //开始发送广播之前会打印类似“power_screen_broadcast_send: 1”的日志
            //这里会在event log中打印类似“power_screen_broadcast_done: [1,125,1]“的日志
			//里面包含了发送亮屏广播的时间,此处是“125 ms”
            EventLog.writeEvent(EventLogTags.POWER_SCREEN_BROADCAST_DONE, 1,
                    SystemClock.uptimeMillis() - mBroadcastStartTime, 1);
            sendNextBroadcast();
        }
    };

   private void sendWakeUpBroadcast() {
        if (DEBUG) {
            Slog.d(TAG, "Sending wake up broadcast.");
        }

        if (mActivityManagerInternal.isSystemReady()) {
            //调用的是ContextImpl的sendOrderedBroadcastAsUser去发送广播
			//mScreenOnIntent是发送的亮屏广播
			//mHandler是PowerManagerService.java的主线程,用来运行mWakeUpBroadcastDone
			//mWakeUpBroadcastDone是亮屏广播发送完成后
            mContext.sendOrderedBroadcastAsUser(mScreenOnIntent, UserHandle.ALL, null,
                    mWakeUpBroadcastDone, mHandler, 0, null, null);
        } else {
            EventLog.writeEvent(EventLogTags.POWER_SCREEN_BROADCAST_STOP, 2, 1);
            sendNextBroadcast();
        }
    }

//ContextImpl.java
    public void sendOrderedBroadcastAsUser(Intent intent, UserHandle user,
            String receiverPermission, BroadcastReceiver resultReceiver, Handler scheduler,
            int initialCode, String initialData, Bundle initialExtras) {
		//多带了appOp=OP_NONE、options=null的参数
        sendOrderedBroadcastAsUser(intent, user, receiverPermission, AppOpsManager.OP_NONE,
                null, resultReceiver, scheduler, initialCode, initialData, initialExtras);
    }

    public void sendOrderedBroadcastAsUser(Intent intent, UserHandle user,
            String receiverPermission, int appOp, Bundle options, BroadcastReceiver resultReceiver,
            Handler scheduler, int initialCode, String initialData, Bundle initialExtras) {
        IIntentReceiver rd = null;
        if (resultReceiver != null) {
            if (mPackageInfo != null) {
                if (scheduler == null) {
                    //由于传入了scheduler(mHandler),所以这里是不会进来的
                    scheduler = mMainThread.getHandler();
                }
				//进入的是这里获取IIntentReceiver rd(通过mPackageInfo、resultReceiver、scheduler构建)
                rd = mPackageInfo.getReceiverDispatcher(
                    resultReceiver, getOuterContext(), scheduler,
                    mMainThread.getInstrumentation(), false);
            } else {
                if (scheduler == null) {
                    scheduler = mMainThread.getHandler();
                }
                rd = new LoadedApk.ReceiverDispatcher(resultReceiver, getOuterContext(),
                        scheduler, null, false).getIIntentReceiver();
            }
        }
        String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
        String[] receiverPermissions = receiverPermission == null ? null
                : new String[] {receiverPermission};
        try {
            intent.prepareToLeaveProcess(this);
			//实际是调用的AMS的broadcastIntentWithFeature方法
            ActivityManager.getService().broadcastIntentWithFeature(
                    mMainThread.getApplicationThread(), getAttributionTag(), intent, resolvedType,
                    rd, initialCode, initialData, initialExtras, receiverPermissions,
                    null /*excludedPermissions=*/, appOp, options, true, false,
                    user.getIdentifier());
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
        }
    }

3. 系统处理广播发送

3.1 AMS接收广播的请求

系统AMS通过broadcastIntentWithFeature接收广播的请求

//ActivityManagerService.java
    //从context过来的都走的这个broadcastIntentWithFeature方法,带特性的发送广播
    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) {
        enforceNotIsolatedCaller("broadcastIntent");
        synchronized(this) {
            intent = verifyBroadcastLocked(intent);

			//通过IApplicationThread获取调用者ProcessRecord callerApp
            final ProcessRecord callerApp = getRecordForAppLOSP(caller);
            final int callingPid = Binder.getCallingPid();
            final int callingUid = Binder.getCallingUid();

            final long origId = Binder.clearCallingIdentity();
            try {
                //获取callerApp、callingPid、callingUid用于广播发送参数传入
                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);
            }
        }
    }

    final int broadcastIntentLocked(ProcessRecord callerApp,
            String callerPackage, String callerFeatureId, Intent intent, String resolvedType,
            IIntentReceiver resultTo, int resultCode, String resultData,
            Bundle resultExtras, String[] requiredPermissions, String[] excludedPermissions,
            int appOp, Bundle bOptions, boolean ordered, boolean sticky, int callingPid,
            int callingUid, int realCallingUid, int realCallingPid, int userId) {
        //这里再次增加了3个参数allowBackgroundActivityStarts=false,tokenNeededForBackgroundActivityStarts=false
		//broadcastAllowList=null
        return broadcastIntentLocked(callerApp, callerPackage, callerFeatureId, intent,
                resolvedType, resultTo, resultCode, resultData, resultExtras, requiredPermissions,
                excludedPermissions, appOp, bOptions, ordered, sticky, callingPid, callingUid,
                realCallingUid, realCallingPid, userId, false /* allowBackgroundActivityStarts */,
                null /* tokenNeededForBackgroundActivityStarts */, null /* broadcastAllowList */);
    }

3.2 修改增加默认flag解析可选广播参数BroadcastOptions

  1. 如默认会增加 FLAG_EXCLUDE_STOPPED_PACKAGES ,不让stop(如通过forcestop会设置)的三方app接收静态广播
  2. 根据是否粘性广播输出类似的日志:Broadcast (sticky) intent ordered=(true/false) userid=(userId)
  3. 解析BroadcastOptions brOptions广播可选参数
    @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,
                                    String[] excludedPermissions, int appOp, Bundle bOptions,
                                    boolean ordered, boolean sticky, int callingPid, int callingUid,
                                    int realCallingUid, int realCallingPid, int userId,
                                    boolean allowBackgroundActivityStarts,
                                    @Nullable IBinder backgroundActivityStartsToken,
                                    @Nullable int[] broadcastAllowList) {
        intent = new Intent(intent);
        //调用者是否即时app
        final boolean callerInstantApp = isInstantApp(callerApp, callerPackage, callingUid);
        // Instant Apps cannot use FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS
        //如果调用者是即时app,不能添加FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS,可以让即时app接收的flag
        if (callerInstantApp) {
            intent.setFlags(intent.getFlags() & ~Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS);
        }

        // broadcastAllowList: 允许接收该广播uid的列表;一般包信息改变的时候才会传入,通过ContextImpl发送广播是不带这个参数的
        // broadcastAllowList目前只在PMS的doSendBroadcast发送package相关广播的时候才可能使用到
        // PackageManagerService.sendPackageBroadcast/sendMyPackageSuspendedOrUnsuspended->doSendBroadcast->
        // ActivityManagerService.LocalService.broadcastIntent
        if (userId == UserHandle.USER_ALL && broadcastAllowList != null) {
            Slog.e(TAG, "broadcastAllowList only applies when sending to individual users. "
                    + "Assuming restrictive whitelist.");
            broadcastAllowList = new int[]{};
        }

        // By default broadcasts do not go to stopped apps.
        //默认广播是不发送给stop的应用的,类似于安装后进程从未启动过,或者给强行停止的应用,
        //是无法通过接收静态注册的广播来启动的(具体在IntentResolver.java的buildResolveList会使用)
        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);

        // If we have not finished booting, don't allow this to launch new processes.
        //mProcessesReady在systemReady的时候会设置为true
        //在系统没有启动完成的时候,而且广播发送没有带FLAG_RECEIVER_BOOT_UPGRADE的flag
        if (!mProcessesReady && (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
            //则默认只能发送到动态注册的接收者中,静态注册的全部无法接收
            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
        }

        //DEBUG_BROADCAST_LIGHT这个是调试日志的开关,这里输出是否order有序广播
        if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG_BROADCAST,
                (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
                        + " ordered=" + ordered + " userid=" + userId);

        //如果是非ordered的广播,而且有resultTo则输出warning的信息
        //一般情况下orderd的广播才会设置resultTo(发送完成后返回完成的结果到发送者)
        if ((resultTo != null) && !ordered) {
            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
        }

        //多用户判断,如果是callingUid、userId同一个用户组,则直接返回userId
        userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
                ALLOW_NON_FULL, "broadcast", callerPackage);

        // Make sure that the user who is receiving this broadcast or its parent is running.
        // If not, we will just skip it. Make an exception for shutdown broadcasts, upgrade steps.
        //如果userId不是发送到所有用户USER_ALL(-1),而且当前userId和它的父亲userId都没有在运行
        if (userId != UserHandle.USER_ALL && !mUserController.isUserOrItsParentRunning(userId)) {
            //如果调用者不是系统或者没有设置FLAG_RECEIVER_BOOT_UPGRADE,而且不是关机广播,
            //则跳过本次广播发送,不允许stop的userId发送广播,原因是user已经stop了
            if ((callingUid != SYSTEM_UID
                    || (intent.getFlags() & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0)
                    && !Intent.ACTION_SHUTDOWN.equals(intent.getAction())) {
                Slog.w(TAG, "Skipping broadcast of " + intent
                        + ": user " + userId + " and its parent (if any) are stopped");
                return ActivityManager.BROADCAST_FAILED_USER_STOPPED;
            }
        }

        //获取其意图的action
        final String action = intent.getAction();
        BroadcastOptions brOptions = null;
        //是否有传入BroadcastOptions的Bundle,开机广播有传入bOptions,亮屏幕广播没有bOptions
        if (bOptions != null) {
            //将Bundle转换成BroadcastOptions brOptions
            brOptions = new BroadcastOptions(bOptions);
            //如果mTemporaryAppAllowlistDuration的值大于0
            if (brOptions.getTemporaryAppAllowlistDuration() > 0) {
                // See if the caller is allowed to do this.  Note we are checking against
                // the actual real caller (not whoever provided the operation as say a
                // PendingIntent), because that who is actually supplied the arguments.
                // 检查一下realCallingPid/realCallingUid是否拥有CHANGE_DEVICE_IDLE_TEMP_WHITELIST(修改临时白名单)、
                // START_ACTIVITIES_FROM_BACKGROUND(后台启动activity)、
                // START_FOREGROUND_SERVICES_FROM_BACKGROUND(后台启动前台服务)的权限,
                // 如果一个都没有,则不允许发送该广播,并抛出安全异常
                // (在部分情况下callingPid/callingUid调用该发送广播的调用者,
                // 于realCallingPid/realCallingUid真实调用者不是一样的)
                if (checkComponentPermission(CHANGE_DEVICE_IDLE_TEMP_WHITELIST,
                        realCallingPid, realCallingUid, -1, true)
                        != PackageManager.PERMISSION_GRANTED
                        && checkComponentPermission(START_ACTIVITIES_FROM_BACKGROUND,
                        realCallingPid, realCallingUid, -1, true)
                        != PackageManager.PERMISSION_GRANTED
                        && checkComponentPermission(START_FOREGROUND_SERVICES_FROM_BACKGROUND,
                        realCallingPid, realCallingUid, -1, true)
                        != PackageManager.PERMISSION_GRANTED) {
                    String msg = "Permission Denial: " + intent.getAction()
                            + " broadcast from " + callerPackage + " (pid=" + callingPid
                            + ", uid=" + callingUid + ")"
                            + " requires "
                            + CHANGE_DEVICE_IDLE_TEMP_WHITELIST + " or "
                            + START_ACTIVITIES_FROM_BACKGROUND + " or "
                            + START_FOREGROUND_SERVICES_FROM_BACKGROUND;
                    Slog.w(TAG, msg);
                    throw new SecurityException(msg);
                }
            }

            //如果带有mDontSendToRestrictedApps不发送给受限制的app
            // callingUid不在mActiveUids中,而且callingUid/callerPackage后台限制操作
            // 则由于“background restrictions”不允许发送广播
            if (brOptions.isDontSendToRestrictedApps()
                    && !isUidActiveLOSP(callingUid)
                    && isBackgroundRestrictedNoCheck(callingUid, callerPackage)) {
                Slog.i(TAG, "Not sending broadcast " + action + " - app " + callerPackage
                        + " has background restrictions");
                return ActivityManager.START_CANCELED;
            }
            //是否允许mAllowBackgroundActivityStarts后台启动activity
            if (brOptions.allowsBackgroundActivityStarts()) {
                // See if the caller is allowed to do this.  Note we are checking against
                // the actual real caller (not whoever provided the operation as say a
                // PendingIntent), because that who is actually supplied the arguments.
                //如果没有START_ACTIVITIES_FROM_BACKGROUND则抛出权限异常
                if (checkComponentPermission(
                        android.Manifest.permission.START_ACTIVITIES_FROM_BACKGROUND,
                        realCallingPid, realCallingUid, -1, true)
                        != PackageManager.PERMISSION_GRANTED) {
                    String msg = "Permission Denial: " + intent.getAction()
                            + " broadcast from " + callerPackage + " (pid=" + callingPid
                            + ", uid=" + callingUid + ")"
                            + " requires "
                            + android.Manifest.permission.START_ACTIVITIES_FROM_BACKGROUND;
                    Slog.w(TAG, msg);
                    throw new SecurityException(msg);
                } else {
                    //否者将allowBackgroundActivityStarts设置成true,允许后台启动activity
                    allowBackgroundActivityStarts = true;
                    // We set the token to null since if it wasn't for it we'd allow anyway here
                    backgroundActivityStartsToken = null;
                }
            }
        }

3.4 保护广播isProtectedBroadcast、特定action的处理

  1. 识别是否保护广播,这类广播不能给系统之外的app调用;而系统尽量发送保护广播,不然也会发出警告
  2. 后台是否可以接收广播的识别(如果在system/etc、/product/etc等地方加入“allow-implicit-broadcast”的广播则可以让后台接收,
    会加上FLAG_RECEIVER_INCLUDE_BACKGROUND的flag)
  3. 特定action如包状态改变等的广播的处理
        // Verify that protected broadcasts are only being sent by system code,
        // and that system code is only sending protected broadcasts.
        //保护广播的判断逻辑isProtectedBroadcast,这类广播只有系统才能发送
        final boolean isProtectedBroadcast;
        try {
            //查询该广播是否包含在mProtectedBroadcasts,在isProtectedBroadcast也可以增加字符串过滤条件
            //例如在frameworks/base/core/res/AndroidManifest.xml等定义的带有“protected-broadcast”的广播
            // <protected-broadcast android:name="android.intent.action.SCREEN_ON" />
            isProtectedBroadcast = AppGlobals.getPackageManager().isProtectedBroadcast(action);
        } catch (RemoteException e) {
            Slog.w(TAG, "Remote exception", e);
            return ActivityManager.BROADCAST_SUCCESS;
        }

        final boolean isCallerSystem;
        //判断是否系统调用
        switch (UserHandle.getAppId(callingUid)) {
            case ROOT_UID:
            case SYSTEM_UID:
            case PHONE_UID:
            case BLUETOOTH_UID:
            case NFC_UID:
            case SE_UID:
            case NETWORK_STACK_UID:
                //root用户、系统、phone、蓝牙、nfc、安全、网络等相关调用则被认为是系统
                isCallerSystem = true;
                break;
            default:
                //其它就看是否常驻内存,如果是常驻内存调用,也被认为是系统
                isCallerSystem = (callerApp != null) && callerApp.isPersistent();
                break;
        }

        // First line security check before anything else: stop non-system apps from
        // sending protected broadcasts.
        //如果不是系统调用,会进行安全检查
        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);

            } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)
                    || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)) {
                // Special case for compatibility: we don't want apps to send this,
                // but historically it has not been protected and apps may be using it
                // to poke their own app widget.  So, instead of making it protected,
                // just limit it to the caller.
                //如果是widget配置(ACTION_APPWIDGET_CONFIGURE)和更新(ACTION_APPWIDGET_UPDATE)
                //则调用callerPackage不能是空
                if (callerPackage == null) {
                    String msg = "Permission Denial: not allowed to send broadcast "
                            + action + " from unknown caller.";
                    Slog.w(TAG, msg);
                    throw new SecurityException(msg);
                //如果调用组件不等于null
                } else if (intent.getComponent() != null) {
                    // They are good enough to send to an explicit component...  verify
                    // it is being sent to the calling app.
                    //这种情况只能自己发送给自己,不然抛出权限异常
                    if (!intent.getComponent().getPackageName().equals(
                            callerPackage)) {
                        String msg = "Permission Denial: not allowed to send broadcast "
                                + action + " to "
                                + intent.getComponent().getPackageName() + " from "
                                + callerPackage;
                        Slog.w(TAG, msg);
                        throw new SecurityException(msg);
                    }
                } else {
                    // Limit broadcast to their own package.
                    //这类广播只能发给它自己,用于自身widget的更新
                    intent.setPackage(callerPackage);
                }
            }
        }

        //这个是广播超时豁免只有ACTION_PRE_BOOT_COMPLETED才会设置
        //设置了之后这个广播不会超时,谨慎使用
        boolean timeoutExempt = false;

        if (action != null) {
            //查看是否background的进程也可以接收该广播,具体列表在SystemConfig.java的mAllowImplicitBroadcasts
            //这个列表是扫描**/etc(如system/etc/sysconfig/framework-sysconfig.xml、
            // /product/etc/sysconfig/google.xml)带有“<allow-implicit-broadcast”的广播
            // 如:google的云推送”com.google.android.c2dm.intent.RECEIVE“、simcard状态改变
            // android.intent.action.SIM_STATE_CHANGED就是这类广播
            if (getBackgroundLaunchBroadcasts().contains(action)) {
                if (DEBUG_BACKGROUND_CHECK) {
                    Slog.i(TAG, "Broadcast action " + action + " forcing include-background");
                }
                //直接增加可以被后台进程接收的flag FLAG_RECEIVER_INCLUDE_BACKGROUND
                // (如何使用在讲解BroadcastQueue的processNextBroadcastLocked时会说明)
                intent.addFlags(Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
            }

            switch (action) {
                case Intent.ACTION_UID_REMOVED:
                case Intent.ACTION_PACKAGE_REMOVED:
                case Intent.ACTION_PACKAGE_CHANGED:
                case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
                case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
                case Intent.ACTION_PACKAGES_SUSPENDED:
                case Intent.ACTION_PACKAGES_UNSUSPENDED:
                    // Handle special intents: if this broadcast is from the package
                    // manager about a package being removed, we need to remove all of
                    // its activities from the history stack.
                    // 如果是ACTION_UID_REMOVED/ACTION_PACKAGE_REMOVED/ACTION_PACKAGE_CHANGED/
                    // ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE/ACTION_EXTERNAL_APPLICATIONS_AVAILABLE/
                    // ACTION_PACKAGES_SUSPENDED/ACTION_PACKAGES_UNSUSPENDED这类广播,
                    // 则发送广播需要BROADCAST_PACKAGE_REMOVED的权限,不然是没法发送的
                    if (checkComponentPermission(
                            android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
                            callingPid, callingUid, -1, true)
                            != PackageManager.PERMISSION_GRANTED) {
                        String msg = "Permission Denial: " + intent.getAction()
                                + " broadcast from " + callerPackage + " (pid=" + callingPid
                                + ", uid=" + callingUid + ")"
                                + " requires "
                                + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
                        Slog.w(TAG, msg);
                        throw new SecurityException(msg);
                    }
                    switch (action) {
                        case Intent.ACTION_UID_REMOVED:
                            final int uid = getUidFromIntent(intent);
                            //如果发送的是ACTION_UID_REMOVED的广播
                            if (uid >= 0) {
                                //电池状态服务的removeUid
                                mBatteryStatsService.removeUid(uid);
                                //mAppOpsService app操作相关管理的处理
                                if (intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) {
                                    mAppOpsService.resetAllModes(UserHandle.getUserId(uid),
                                            intent.getStringExtra(Intent.EXTRA_PACKAGE_NAME));
                                } else {
                                    mAppOpsService.uidRemoved(uid);
                                }
                            }
                            break;
                        case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
                            // If resources are unavailable just force stop all those packages
                            // and flush the attribute cache as well.
                            String list[] =
                                    intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
                            if (list != null && list.length > 0) {
                                for (int i = 0; i < list.length; i++) {
                                    forceStopPackageLocked(list[i], -1, false, true, true,
                                            false, false, userId, "storage unmount");
                                }
                                mAtmInternal.cleanupRecentTasksForUser(UserHandle.USER_ALL);
                                sendPackageBroadcastLocked(
                                        ApplicationThreadConstants.EXTERNAL_STORAGE_UNAVAILABLE,
                                        list, userId);
                            }
                            break;
                        case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
                            mAtmInternal.cleanupRecentTasksForUser(UserHandle.USER_ALL);
                            break;
                        case Intent.ACTION_PACKAGE_REMOVED:
                        case Intent.ACTION_PACKAGE_CHANGED:
                            //应用移除或者改变
                            Uri data = intent.getData();
                            String ssp;
                            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
                                boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(action);
                                final boolean replacing =
                                        intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
                                final boolean killProcess =
                                        !intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false);
                                final boolean fullUninstall = removed && !replacing;
                                if (removed) {
                                    if (killProcess) {
                                        forceStopPackageLocked(ssp, UserHandle.getAppId(
                                                intent.getIntExtra(Intent.EXTRA_UID, -1)),
                                                false, true, true, false, fullUninstall, userId,
                                                removed ? "pkg removed" : "pkg changed");
                                    } else {
                                        // Kill any app zygotes always, since they can't fork new
                                        // processes with references to the old code
                                        forceStopAppZygoteLocked(ssp, UserHandle.getAppId(
                                                intent.getIntExtra(Intent.EXTRA_UID, -1)),
                                                userId);
                                    }
                                    final int cmd = killProcess
                                            ? ApplicationThreadConstants.PACKAGE_REMOVED
                                            : ApplicationThreadConstants.PACKAGE_REMOVED_DONT_KILL;
                                    sendPackageBroadcastLocked(cmd,
                                            new String[] {ssp}, userId);
                                    if (fullUninstall) {
                                        mAppOpsService.packageRemoved(
                                                intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);

                                        // Remove all permissions granted from/to this package
                                        mUgmInternal.removeUriPermissionsForPackage(ssp, userId,
                                                true, false);

                                        mAtmInternal.removeRecentTasksByPackageName(ssp, userId);

                                        mServices.forceStopPackageLocked(ssp, userId);
                                        mAtmInternal.onPackageUninstalled(ssp);
                                        mBatteryStatsService.notePackageUninstalled(ssp);
                                    }
                                } else {
                                    if (killProcess) {
                                        final int extraUid = intent.getIntExtra(Intent.EXTRA_UID,
                                                -1);
                                        synchronized (mProcLock) {
                                            mProcessList.killPackageProcessesLSP(ssp,
                                                    UserHandle.getAppId(extraUid),
                                                    userId, ProcessList.INVALID_ADJ,
                                                    ApplicationExitInfo.REASON_USER_REQUESTED,
                                                    ApplicationExitInfo.SUBREASON_UNKNOWN,
                                                    "change " + ssp);
                                        }
                                    }
                                    cleanupDisabledPackageComponentsLocked(ssp, userId,
                                            intent.getStringArrayExtra(
                                                    Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST));
                                    mServices.schedulePendingServiceStartLocked(ssp, userId);
                                }                            }
                            break;
                        case Intent.ACTION_PACKAGES_SUSPENDED:
                        case Intent.ACTION_PACKAGES_UNSUSPENDED:
                            final boolean suspended = Intent.ACTION_PACKAGES_SUSPENDED.equals(
                                    intent.getAction());
                            final String[] packageNames = intent.getStringArrayExtra(
                                    Intent.EXTRA_CHANGED_PACKAGE_LIST);
                            final int userIdExtra = intent.getIntExtra(
                                    Intent.EXTRA_USER_HANDLE, UserHandle.USER_NULL);

                            mAtmInternal.onPackagesSuspendedChanged(packageNames, suspended,
                                    userIdExtra);
                            break;
                    }
                    break;
                case Intent.ACTION_PACKAGE_REPLACED:
                {
                    final Uri data = intent.getData();
                    final String ssp;
                    if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
                        ApplicationInfo aInfo = null;
                        try {
                            aInfo = AppGlobals.getPackageManager()
                                    .getApplicationInfo(ssp, STOCK_PM_FLAGS, userId);
                        } catch (RemoteException ignore) {}
                        if (aInfo == null) {
                            Slog.w(TAG, "Dropping ACTION_PACKAGE_REPLACED for non-existent pkg:"
                                    + " ssp=" + ssp + " data=" + data);
                            return ActivityManager.BROADCAST_SUCCESS;
                        }
                        updateAssociationForApp(aInfo);
                        mAtmInternal.onPackageReplaced(aInfo);
                        mServices.updateServiceApplicationInfoLocked(aInfo);
                        sendPackageBroadcastLocked(ApplicationThreadConstants.PACKAGE_REPLACED,
                                new String[] {ssp}, userId);
                    }
                    break;
                }
                case Intent.ACTION_PACKAGE_ADDED:
                {
                    //应用安装
                    // Special case for adding a package: by default turn on compatibility mode.
                    Uri data = intent.getData();
                    String ssp;
                    if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
                        final boolean replacing =
                                intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
                        mAtmInternal.onPackageAdded(ssp, replacing);
                        try {
                            ApplicationInfo ai = AppGlobals.getPackageManager().
                                    getApplicationInfo(ssp, STOCK_PM_FLAGS, 0);
                            mBatteryStatsService.notePackageInstalled(ssp,
                                    ai != null ? ai.longVersionCode : 0);
                        } catch (RemoteException e) {
                        }
                    }
                    break;
                }
                case Intent.ACTION_PACKAGE_DATA_CLEARED:
                {
                    //应用数据清除
                    Uri data = intent.getData();
                    String ssp;
                    if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
                        mAtmInternal.onPackageDataCleared(ssp);
                    }
                    break;
                }
                case Intent.ACTION_TIMEZONE_CHANGED:
                    // If this is the time zone changed action, queue up a message that will reset
                    // the timezone of all currently running processes. This message will get
                    // queued up before the broadcast happens.
                    //时区改变
                    mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
                    break;
                case Intent.ACTION_TIME_CHANGED:
                    // EXTRA_TIME_PREF_24_HOUR_FORMAT is optional so we must distinguish between
                    // the tri-state value it may contain and "unknown".
                    // For convenience we re-use the Intent extra values.
                    //系统时间改变
                    final int NO_EXTRA_VALUE_FOUND = -1;
                    final int timeFormatPreferenceMsgValue = intent.getIntExtra(
                            Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT,
                            NO_EXTRA_VALUE_FOUND /* defaultValue */);
                    // Only send a message if the time preference is available.
                    if (timeFormatPreferenceMsgValue != NO_EXTRA_VALUE_FOUND) {
                        Message updateTimePreferenceMsg =
                                mHandler.obtainMessage(UPDATE_TIME_PREFERENCE_MSG,
                                        timeFormatPreferenceMsgValue, 0);
                        mHandler.sendMessage(updateTimePreferenceMsg);
                    }
                    mBatteryStatsService.noteCurrentTimeChanged();
                    break;
                case ConnectivityManager.ACTION_CLEAR_DNS_CACHE:
                    mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
                    break;
                case Proxy.PROXY_CHANGE_ACTION:
                    mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG));
                    break;
                case android.hardware.Camera.ACTION_NEW_PICTURE:
                case android.hardware.Camera.ACTION_NEW_VIDEO:
                    // In N we just turned these off; in O we are turing them back on partly,
                    // only for registered receivers.  This will still address the main problem
                    // (a spam of apps waking up when a picture is taken putting significant
                    // memory pressure on the system at a bad point), while still allowing apps
                    // that are already actively running to know about this happening.
                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
                    break;
                case android.security.KeyChain.ACTION_TRUST_STORE_CHANGED:
                    mHandler.sendEmptyMessage(HANDLE_TRUST_STORAGE_UPDATE_MSG);
                    break;
                case "com.android.launcher.action.INSTALL_SHORTCUT":
                    // As of O, we no longer support this broadcasts, even for pre-O apps.
                    // Apps should now be using ShortcutManager.pinRequestShortcut().
                    Log.w(TAG, "Broadcast " + action
                            + " no longer supported. It will not be delivered.");
                    return ActivityManager.BROADCAST_SUCCESS;
                case Intent.ACTION_PRE_BOOT_COMPLETED:
                    //如果是ACTION_PRE_BOOT_COMPLETED广播则设置超时豁免timeoutExempt = true
                    timeoutExempt = true;
                    break;
                case Intent.ACTION_CLOSE_SYSTEM_DIALOGS:
                    //需要有BROADCAST_CLOSE_SYSTEM_DIALOGS的权限,不然直接返回
                    if (!mAtmInternal.checkCanCloseSystemDialogs(callingPid, callingUid,
                            callerPackage)) {
                        // Returning success seems to be the pattern here
                        return ActivityManager.BROADCAST_SUCCESS;
                    }
                    break;
            }

            if (Intent.ACTION_PACKAGE_ADDED.equals(action) ||
                    Intent.ACTION_PACKAGE_REMOVED.equals(action) ||
                    Intent.ACTION_PACKAGE_REPLACED.equals(action)) {
                final int uid = getUidFromIntent(intent);
                if (uid != -1) {
                    final UidRecord uidRec = mProcessList.getUidRecordLOSP(uid);
                    if (uidRec != null) {
                        uidRec.updateHasInternetPermission();
                    }
                }
            }
        }

3.5 发送粘性广播的处理

将粘性广播添加到AMS的mStickyBroadcasts(key是用户组,value是粘性广播列表stickies)中,
单个用户组的粘性广播列表stickies(key是action,value是intent)

已经发送的粘性广播会放入AMS的mStickyBroadcasts中,后面动态注册的接收者就可以在注册的时候就接收这类粘性广播, 因为系统有保存这类广播

        // Add to the sticky list if requested.
        // 是否粘性广播,可以通过ContextImpl.java的sendStickyBroadcast/sendStickyBroadcastAsUser/
        // sendStickyOrderedBroadcast/sendStickyOrderedBroadcastAsUser来进行发送
        if (sticky) {
            //粘性广播需要拥有"android.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);
            }
            //这类广播不能带有requiredPermissions,否则直接返回
            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");
            }
            // We use userId directly here, since the "all" target is maintained
            // as a separate set of sticky broadcasts.
            //如果userId不是发送给所有用户USER_ALL(-1)
            if (userId != UserHandle.USER_ALL) {
                // But first, if this is not a broadcast to all users, then
                // make sure it doesn't conflict with an existing broadcast to
                // all users.
                //则取出保存粘性广播的列表mStickyBroadcasts里面相同action的Intent
                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
                        UserHandle.USER_ALL);
                if (stickies != null) {
                    ArrayList<Intent> list = stickies.get(intent.getAction());
                    if (list != null) {
                        int N = list.size();
                        int i;
                        for (i=0; i<N; i++) {
                            //粘性广播2个Intent不能完全相同,相同的话会抛出非法参数异常
                            //mAction/mData/mType/mIdentifier/mPackage/mComponent/mCategories都一致filterEquals才会返回true
                            if (intent.filterEquals(list.get(i))) {
                                throw new IllegalArgumentException(
                                        "Sticky broadcast " + intent + " for user "
                                                + userId + " conflicts with existing global broadcast");
                            }
                        }
                    }
                }
            }

            //获取该用户组的粘性广播列表stickies
            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
            if (stickies == null) {
                //如果stickies是null,则新建一个
                stickies = new ArrayMap<>();
                //并添加到mStickyBroadcasts中key为userId中去
                mStickyBroadcasts.put(userId, stickies);
            }

            //通过粘性广播列表stickies(key是action,value是intent)
            ArrayList<Intent> list = stickies.get(intent.getAction());
            if (list == null) {
                //如果list为空,则新建一个ArrayList,并放入stickies
                list = new ArrayList<>();
                stickies.put(intent.getAction(), list);
            }
            final int stickiesCount = list.size();
            int i;
            for (i = 0; i < stickiesCount; i++) {
                //mAction/mData/mType/mIdentifier/mPackage/mComponent/mCategories都一致filterEquals才会返回true
                if (intent.filterEquals(list.get(i))) {
                    // This sticky already exists, replace it.
                    //如果之前存在一样的intent,则直接替换掉旧的,并且退出循环
                    list.set(i, new Intent(intent));
                    break;
                }
            }
            //如果上面中途替换过list的intent,则i < stickiesCount
            //而i >= stickiesCount则代表没有替换过
            if (i >= stickiesCount) {
                //没有替换过则加入list中去
                list.add(new Intent(intent));
            }
        }

3.6 筛选出静态广播接受者

  1. 这里主要是通过collectReceiverComponents来筛选出静态广播接受者
        int[] users;
        //通过userId,获取多用户的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.
		// 静态广播接受者或者order的动态广播接受者的列表
        List receivers = null;
		// 动态广播接受者列表
        List<BroadcastFilter> registeredReceivers = null;
        // Need to resolve the intent to interested receivers...
        //静态广播的接收,只要没有设置FLAG_RECEIVER_REGISTERED_ONLY,都会查询发送到静态广播中,
        //不过如常见的Intent.ACTION_SCREEN_ON则发送时则有设置这个flag,于是Intent.ACTION_SCREEN_ON不会发送给静态广播
        //不要注册Intent.ACTION_SCREEN_ON的静态广播,这个注册了你也收不到
        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
                == 0) {
            //这里就是查询静态广播的地方,通过PMS的mComponentResolver查询得到该intent静态注册的广播接受者
            //同时传入broadcastAllowList过滤是否允许接受者接收
            receivers = collectReceiverComponents(
                    intent, resolvedType, callingUid, users, broadcastAllowList);
        }
  1. collectReceiverComponents函数

collectReceiverComponents:收集静态接收者的函数,其调用的是PMS的queryIntentReceivers进行查询,然后进行相应过滤。
=> 调用的是PMS的queryIntentReceivers进行查询
=> 判断是否只发送到单个用户FLAG_SYSTEM_USER_ONLY(多用户场景使用),如果是则进行过滤,只发送给单个用户
=> 如果带有broadcastAllowList(允许接收该广播uid的列表),则只让特定uid列表的静态接收者接收

    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
                                                        int callingUid, int[] users, int[] broadcastAllowList) {
        // TODO: come back and remove this assumption to triage all broadcasts
        int pmFlags = STOCK_PM_FLAGS | MATCH_DEBUG_TRIAGED_MISSING;

        List<ResolveInfo> receivers = null;
        try {
            HashSet<ComponentName> singleUserReceivers = null;
            boolean scannedFirstReceivers = false;
            for (int user : users) {
                // Skip users that have Shell restrictions
                //如果调用者是shell,而且该user不允许shell调试,则跳过
                if (callingUid == SHELL_UID
                        && mUserController.hasUserRestriction(
                        UserManager.DISALLOW_DEBUGGING_FEATURES, user)) {
                    continue;
                }
                //静态广播通过PMS去查询接收者
                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
                        .queryIntentReceivers(intent, resolvedType, pmFlags, user).getList();
                if (user != UserHandle.USER_SYSTEM && newReceivers != null) {
                    // If this is not the system user, we need to check for
                    // any receivers that should be filtered out.
                    for (int i=0; i<newReceivers.size(); i++) {
                        ResolveInfo ri = newReceivers.get(i);
                        //如果取出来的ResolveInfo包含了只允许系统接收的flag(FLAG_SYSTEM_USER_ONLY),
                        //则从筛选出来的列表中移除这个接收者
                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SYSTEM_USER_ONLY) != 0) {
                            newReceivers.remove(i);
                            i--;
                        }
                    }
                }
                //如果到目前为止newReceivers(ResolveInfo列表)为null或者空的
                if (newReceivers != null && newReceivers.size() == 0) {
                    newReceivers = null;
                }
                if (receivers == null) {
                    //如果receivers(最后返回的结果)为null,则先将newReceivers赋值给receivers
                    receivers = newReceivers;
                } else if (newReceivers != null) {
                    // We need to concatenate the additional receivers
                    // found with what we have do far.  This would be easy,
                    // but we also need to de-dup any receivers that are
                    // singleUser.
                    //scannedFirstReceivers默认是fasle,也就是第一次跑到这段代码会进来,只进来一次
                    //receivers此时已经赋值过一次,这里是users第二次和以上循环才可能会进来
                    if (!scannedFirstReceivers) {
                        // Collect any single user receivers we had already retrieved.
                        scannedFirstReceivers = true;
                        // 遍历之前的receivers(这里receivers没有判空逻辑,只看这段逻辑不太严谨,
                        // 没有出错是由于newReceivers有判空)
                        for (int i=0; i<receivers.size(); i++) {
                            ResolveInfo ri = receivers.get(i);
                            //如果接收者包含FLAG_SINGLE_USER的flag
                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
                                ComponentName cn = new ComponentName(
                                        ri.activityInfo.packageName, ri.activityInfo.name);
                                if (singleUserReceivers == null) {
                                    singleUserReceivers = new HashSet<ComponentName>();
                                }
                                //则把这类组件add到singleUserReceivers中
                                singleUserReceivers.add(cn);
                            }
                        }
                    }
                    // Add the new results to the existing results, tracking
                    // and de-dupping single user receivers.
                    // 遍历新的users中获取的newReceivers
                    for (int i=0; i<newReceivers.size(); i++) {
                        ResolveInfo ri = newReceivers.get(i);
                        //如果也是带有FLAG_SINGLE_USER的flag,只发送给单个user
                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
                            ComponentName cn = new ComponentName(
                                    ri.activityInfo.packageName, ri.activityInfo.name);
                            if (singleUserReceivers == null) {
                                singleUserReceivers = new HashSet<ComponentName>();
                            }
                            //如果之前还没有添加过,才进行receivers添加
                            if (!singleUserReceivers.contains(cn)) {
                                //而且将单个用户接受者ComponentName cn添加到ComponentName中
                                singleUserReceivers.add(cn);
                                receivers.add(ri);
                            }
                        } else {
                            //其它情况则直接加入该接收者到receivers
                            receivers.add(ri);
                        }
                    }
                }
            }
        } catch (RemoteException ex) {
            // pm is in same process, this will never happen.
        }
        //如果带有broadcastAllowList,允许接收该广播uid的列表
        if (receivers != null && broadcastAllowList != null) {
            for (int i = receivers.size() - 1; i >= 0; i--) {
                final int receiverAppId = UserHandle.getAppId(
                        receivers.get(i).activityInfo.applicationInfo.uid);
                //接受者的uid如果是app进程,而且不在允许接收该广播uid的列表,则移除查询到的接收者
                if (receiverAppId >= Process.FIRST_APPLICATION_UID
                        && Arrays.binarySearch(broadcastAllowList, receiverAppId) < 0) {
                    receivers.remove(i);
                }
            }
        }
        //返回接受者
        return receivers;
    }
  1. PMS通过包安装信息获得静态接收者

=> 如果包发送给特定组件,则通过mComponentResolver的mReceivers.mActivities获取ParsedActivity,并最终得到对应的ActivityInfo
=> 如果没有指定特定组件和特定包,则通过mComponentResolver查询recevier,
调用的是IntentResolver的queryIntent,根据各类Filter去查询,如mActionToFilter,
查询到结果后在通过buildResolveList构建返回的结果List result
=> 如果是发送给特定包,则通过mPackages(安装的时候保存的,key是包名,
value是AndroidPackage/ParsingPackageImpl/PackageImpl)获取AndroidPackage(ParsingPackageImpl),
通过ParsingPackageImpl得到这个包的receivers(pkg.getReceivers()),
然后通过mComponentResolver的queryReceivers(ComponentResolver.java)->mReceivers.queryIntentForPackage
queryIntentFromList(IntentResolver.java)->buildResolveList
此处queryIntentFromList只查询这个包的receivers(构建Pair<ParsedActivity, ParsedIntentInfo>来查询)

在这里可以看到之前“Android S静态广播注册流程”中提到的用来保存静态注册广播组件的mComponentResolver、mReceivers.mActivities、receivers

//PackageManagerService.java
    public @NonNull ParceledListSlice<ResolveInfo> queryIntentReceivers(Intent intent,
            String resolvedType, int flags, int userId) {
        //内部方法查询该intent的接受者queryIntentReceiversInternal
        return new ParceledListSlice<>(
                queryIntentReceiversInternal(intent, resolvedType, flags, userId,
                        false /*allowDynamicSplits*/));
    }

    private @NonNull List<ResolveInfo> queryIntentReceiversInternal(Intent intent,
            String resolvedType, int flags, int userId, boolean allowDynamicSplits) {
        //userId不存在则返回空
        if (!mUserManager.exists(userId)) return Collections.emptyList();
        final int callingUid = Binder.getCallingUid();
        //callingUid是否拥有INTERACT_ACROSS_USERS_FULL或者INTERACT_ACROSS_USERS的权限
        enforceCrossUserPermission(callingUid, userId, false /*requireFullPermission*/,
                false /*checkShell*/, "query intent receivers");
        //看一下callingUid是否即时app,如果是则返回包名,如果不是则返回null
        final String instantAppPkgName = getInstantAppPackageName(callingUid);
        //更新一下flags
        flags = updateFlagsForResolve(flags, userId, callingUid, false /*includeInstantApps*/,
                isImplicitImageCaptureIntentAndNotSetByDpcLocked(intent, userId, resolvedType,
                        flags));
        //获取intent意图的ComponentName
        ComponentName comp = intent.getComponent();
        if (comp == null) {
            //如果为空,再从intent的selector中查询组件
            if (intent.getSelector() != null) {
                intent = intent.getSelector();
                comp = intent.getComponent();
            }
        }
        if (comp != null) {
            //如果ComponentName组件不为null,则代表发送给特定的组件
            final List<ResolveInfo> list = new ArrayList<>(1);
            //通过组件获取ActivityInfo
            final ActivityInfo ai = getReceiverInfo(comp, flags, userId);
            if (ai != null) {
                // When specifying an explicit component, we prevent the activity from being
                // used when either 1) the calling package is normal and the activity is within
                // an instant application or 2) the calling package is ephemeral and the
                // activity is not visible to instant applications.
                final boolean matchInstantApp =
                        (flags & PackageManager.MATCH_INSTANT) != 0;
                final boolean matchVisibleToInstantAppOnly =
                        (flags & PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY) != 0;
                final boolean matchExplicitlyVisibleOnly =
                        (flags & PackageManager.MATCH_EXPLICITLY_VISIBLE_ONLY) != 0;
                final boolean isCallerInstantApp =
                        instantAppPkgName != null;
                final boolean isTargetSameInstantApp =
                        comp.getPackageName().equals(instantAppPkgName);
                final boolean isTargetInstantApp =
                        (ai.applicationInfo.privateFlags
                                & ApplicationInfo.PRIVATE_FLAG_INSTANT) != 0;
                final boolean isTargetVisibleToInstantApp =
                        (ai.flags & ActivityInfo.FLAG_VISIBLE_TO_INSTANT_APP) != 0;
                final boolean isTargetExplicitlyVisibleToInstantApp =
                        isTargetVisibleToInstantApp
                        && (ai.flags & ActivityInfo.FLAG_IMPLICITLY_VISIBLE_TO_INSTANT_APP) == 0;
                final boolean isTargetHiddenFromInstantApp =
                        !isTargetVisibleToInstantApp
                        || (matchExplicitlyVisibleOnly && !isTargetExplicitlyVisibleToInstantApp);
                final boolean blockResolution =
                        !isTargetSameInstantApp
                        && ((!matchInstantApp && !isCallerInstantApp && isTargetInstantApp)
                                || (matchVisibleToInstantAppOnly && isCallerInstantApp
                                        && isTargetHiddenFromInstantApp));
                //如果blockResolution为fasle(一般情况除了InstantApp,其它为fasle)
                if (!blockResolution) {
                    ResolveInfo ri = new ResolveInfo();
                    ri.activityInfo = ai;
                    //添加到List<ResolveInfo> list中
                    list.add(ri);
                }
            }
            //将查询到的List<ResolveInfo> list再次做一些判断,看是否需要移除
            return applyPostResolutionFilter(
                    list, instantAppPkgName, allowDynamicSplits, callingUid, false, userId,
                    intent);
        }

        // reader
        synchronized (mLock) {
            //看一下是否有发送给特定的包
            String pkgName = intent.getPackage();
            if (pkgName == null) {
                //如果pkgName为空,则通过mComponentResolver查询recevier
                //调用的是IntentResolver的queryIntent,根据各类Filter去查询,如mActionToFilter
                //查询到结果后在通过buildResolveList构建返回的结果List<ResolveInfo> result
                final List<ResolveInfo> result =
                        mComponentResolver.queryReceivers(intent, resolvedType, flags, userId);
                if (result == null) {
                    return Collections.emptyList();
                }
                //过滤后返回结果
                return applyPostResolutionFilter(
                        result, instantAppPkgName, allowDynamicSplits, callingUid, false, userId,
                        intent);
            }
            //如果有发送给特定的包
            final AndroidPackage pkg = mPackages.get(pkgName);
            if (pkg != null) {
                // 则queryReceivers(ComponentResolver.java)->mReceivers.queryIntentForPackage
                // queryIntentFromList(IntentResolver.java)->buildResolveList
                // 只查询这个包的receivers(构建Pair<ParsedActivity, ParsedIntentInfo>来查询)
                final List<ResolveInfo> result = mComponentResolver.queryReceivers(
                        intent, resolvedType, flags, pkg.getReceivers(), userId);
                if (result == null) {
                    return Collections.emptyList();
                }
                //过滤后返回结果
                return applyPostResolutionFilter(
                        result, instantAppPkgName, allowDynamicSplits, callingUid, false, userId,
                        intent);
            }
            return Collections.emptyList();
        }
    }

	//查询单个组件的ActivityInfo:通过组件名,可以获得相应的ParsedActivity,最终返回的是ActivityInfo信息
    public ActivityInfo getReceiverInfo(ComponentName component, int flags, int userId) {
        if (!mUserManager.exists(userId)) return null;
        final int callingUid = Binder.getCallingUid();
        flags = updateFlagsForComponent(flags, userId);
        enforceCrossUserPermission(callingUid, userId, false /* requireFullPermission */,
                false /* checkShell */, "get receiver info");
        synchronized (mLock) {
            //通过mComponentResolver(mReceivers.mActivities取)查询该组件的ParsedActivity
            ParsedActivity a = mComponentResolver.getReceiver(component);
            if (DEBUG_PACKAGE_INFO) Log.v(
                TAG, "getReceiverInfo " + component + ": " + a);

            if (a == null) {
                //如果没有取出来,则返回null
                return null;
            }

            //mPackages变量是保存了所有安装的应用,查看一下这个package是否能从安装应用中查出来
            AndroidPackage pkg = mPackages.get(a.getPackageName());
            if (pkg == null) {
                return null;
            }

            // 是否包enable(这个是ParsingPackageImpl的ENABLED,不是PackageSettingBase的enabledComponents/disabledComponents)
            // 和匹配
            if (mSettings.isEnabledAndMatchLPr(pkg, a, flags, userId)) {
                //从mSettings中获取包信息PackageSetting ps
                PackageSetting ps = mSettings.getPackageLPr(component.getPackageName());
                if (ps == null) return null;
                //查看一下是否需要根据callingUid过滤是否可见其它目标的package
                //系统调用的话返回false
                if (shouldFilterApplicationLocked(
                        ps, callingUid, component, TYPE_RECEIVER, userId)) {
                    return null;
                }
                //根据pkg和ParsedActivity生成相应的ActivityInfo信息
                return PackageInfoUtils.generateActivityInfo(pkg,
                        a, flags, ps.readUserState(userId), userId, ps);
            }
        }
        return null;
    }

3.7 筛选出动态广播接受者

“Android S动态广播注册流程”中有讲到:动态广播注册其实最终构建的是BroadcastFilter bf,并放入mReceiverResolver中去
而放入mReceiverResolver使用的方法是IntentResolver的addFilter在“Android S静态广播注册流程”也有提到。

  1. 动态广播接受者主要是通过mReceiverResolver的queryIntent来查询得到
        if (intent.getComponent() == null) {
            //如果intent不是单独发给某个组件的话
            //如果userId == UserHandle.USER_ALL(发给所有用户)而且callingUid == SHELL_UID(从shell过来)
            //一般app或者系统发送不是用过这个场景来发送的
            if (userId == UserHandle.USER_ALL && callingUid == SHELL_UID) {
                // Query one target user at a time, excluding shell-restricted users
                for (int i = 0; i < users.length; i++) {
                    if (mUserController.hasUserRestriction(
                            UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) {
                        continue;
                    }
                    //通过动态注册广播的解析器mReceiverResolver,查询动态注册的接受者
                    //也是通过IntentResolver.java的queryIntent来查询的
                    List<BroadcastFilter> registeredReceiversForUser =
                            mReceiverResolver.queryIntent(intent,
                                    resolvedType, false /*defaultOnly*/, users[i]);

                    //将查询到的接受者添加到registeredReceivers中去
                    if (registeredReceivers == null) {
                        registeredReceivers = registeredReceiversForUser;
                    } else if (registeredReceiversForUser != null) {
                        registeredReceivers.addAll(registeredReceiversForUser);
                    }
                }
            } else {
                //一般情况我们走的这里,直接从mReceiverResolver查询动态接受者赋值给registeredReceivers
                registeredReceivers = mReceiverResolver.queryIntent(intent,
                        resolvedType, false /*defaultOnly*/, userId);
            }
        }
  1. IntentResolver的queryIntent函数
    (动态接收者查询的使用mReceiverResolver的queryIntent来查询得到,
    而静态注册查询的使用也是通过mComponentResolver.mReceivers.queryIntent,都是使用一个方法)

=> 通过***Filter(如mActionToFilter)找出匹配的fliter
=> 通过buildResolveList构建可以被接收的结果
=> 通过优先级排序返回查询结果

//IntentResolver.java
    public List<R> queryIntent(Intent intent, String resolvedType, boolean defaultOnly,
                               int userId) {
        String scheme = intent.getScheme();

        ArrayList<R> finalList = new ArrayList<R>();

        final boolean debug = localLOGV ||
                ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);

        if (debug) Slog.v(
                TAG, "Resolving type=" + resolvedType + " scheme=" + scheme
                        + " defaultOnly=" + defaultOnly + " userId=" + userId + " of " + intent);

        F[] firstTypeCut = null;
        F[] secondTypeCut = null;
        F[] thirdTypeCut = null;
        F[] schemeCut = null;

        // If the intent includes a MIME type, then we want to collect all of
        // the filters that match that MIME type.
        if (resolvedType != null) {
            int slashpos = resolvedType.indexOf('/');
            if (slashpos > 0) {
                final String baseType = resolvedType.substring(0, slashpos);
                if (!baseType.equals("*")) {
                    if (resolvedType.length() != slashpos+2
                            || resolvedType.charAt(slashpos+1) != '*') {
                        // Not a wild card, so we can just look for all filters that
                        // completely match or wildcards whose base type matches.
                        firstTypeCut = mTypeToFilter.get(resolvedType);
                        if (debug) Slog.v(TAG, "First type cut: " + Arrays.toString(firstTypeCut));
                        secondTypeCut = mWildTypeToFilter.get(baseType);
                        if (debug) Slog.v(TAG, "Second type cut: "
                                + Arrays.toString(secondTypeCut));
                    } else {
                        // We can match anything with our base type.
                        firstTypeCut = mBaseTypeToFilter.get(baseType);
                        if (debug) Slog.v(TAG, "First type cut: " + Arrays.toString(firstTypeCut));
                        secondTypeCut = mWildTypeToFilter.get(baseType);
                        if (debug) Slog.v(TAG, "Second type cut: "
                                + Arrays.toString(secondTypeCut));
                    }
                    // Any */* types always apply, but we only need to do this
                    // if the intent type was not already */*.
                    thirdTypeCut = mWildTypeToFilter.get("*");
                    if (debug) Slog.v(TAG, "Third type cut: " + Arrays.toString(thirdTypeCut));
                } else if (intent.getAction() != null) {
                    // The intent specified any type ({@literal *}/*).  This
                    // can be a whole heck of a lot of things, so as a first
                    // cut let's use the action instead.
                    firstTypeCut = mTypedActionToFilter.get(intent.getAction());
                    if (debug) Slog.v(TAG, "Typed Action list: " + Arrays.toString(firstTypeCut));
                }
            }
        }

        // If the intent includes a data URI, then we want to collect all of
        // the filters that match its scheme (we will further refine matches
        // on the authority and path by directly matching each resulting filter).
        if (scheme != null) {
            schemeCut = mSchemeToFilter.get(scheme);
            if (debug) Slog.v(TAG, "Scheme list: " + Arrays.toString(schemeCut));
        }

        // If the intent does not specify any data -- either a MIME type or
        // a URI -- then we will only be looking for matches against empty
        // data.
        if (resolvedType == null && scheme == null && intent.getAction() != null) {
            //这里就把所有的ParsedIntentInfo从mActionToFilter取出来了, key是action, value是Pair(ParsedActivity, ParsedIntentInfo)
            //如我们之前动态注册的亮屏广播mDynamicReceiver,静态注册的开机广播MyReceiver

/*
//动态注册的亮屏广播mReceiverResolver.queryIntent时
firstTypeCut = {BroadcastFilter[42]@39131} 
40 = {BroadcastFilter@39150} "BroadcastFilter{8f17ce8 10214/u0 ReceiverList{50ee60b 9948 com.example.myapplication/10214/u0 remote:7781da}}"

//静态注册的开机广播mComponentResolver.mReceivers.queryIntent时
firstTypeCut = {Pair[316]@38034}
107 = {Pair@38369} "Pair{Activity{7d26902 com.example.myapplication/.MyReceiver2} ParsedIntentInfo{a218213}}"
108 = {Pair@38370} "Pair{Activity{3985c50 com.example.myapplication/.MyReceiver} ParsedIntentInfo{9dfde49}}"
*/
            firstTypeCut = mActionToFilter.get(intent.getAction());
            if (debug) Slog.v(TAG, "Action list: " + Arrays.toString(firstTypeCut));
        }

        FastImmutableArraySet<String> categories = getFastIntentCategories(intent);
        if (firstTypeCut != null) {
            buildResolveList(intent, categories, debug, defaultOnly, resolvedType,
                    scheme, firstTypeCut, finalList, userId);
        }
        if (secondTypeCut != null) {
            buildResolveList(intent, categories, debug, defaultOnly, resolvedType,
                    scheme, secondTypeCut, finalList, userId);
        }
        if (thirdTypeCut != null) {
            buildResolveList(intent, categories, debug, defaultOnly, resolvedType,
                    scheme, thirdTypeCut, finalList, userId);
        }
        if (schemeCut != null) {
            buildResolveList(intent, categories, debug, defaultOnly, resolvedType,
                    scheme, schemeCut, finalList, userId);
        }
        //这里对于即时应用才有过滤效果,普通的是直接返回
        filterResults(finalList);
        //通过getPriority优先级排序
        sortResults(finalList);

        if (debug) {
            Slog.v(TAG, "Final result list:");
            for (int i=0; i<finalList.size(); i++) {
                Slog.v(TAG, "  " + finalList.get(i));
            }
        }
        return finalList;
    }

    private void buildResolveList(Intent intent, FastImmutableArraySet<String> categories,
                                  boolean debug, boolean defaultOnly, String resolvedType, String scheme,
                                  F[] src, List<R> dest, int userId) {
        //获取action
        final String action = intent.getAction();
        //获取data
        final Uri data = intent.getData();
        //获取包名
        final String packageName = intent.getPackage();

        //是否flag包含了FLAG_INCLUDE_STOPPED_PACKAGES(发送给停止的包)
        final boolean excludingStopped = intent.isExcludingStopped();

        final Printer logPrinter;
        final PrintWriter logPrintWriter;
        //调试使用的debug开关,localLOGV或者设置了FLAG_DEBUG_LOG_RESOLUTION时debug会是true
        if (debug) {
            logPrinter = new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM);
            logPrintWriter = new FastPrintWriter(logPrinter);
        } else {
            logPrinter = null;
            logPrintWriter = null;
        }

        final int N = src != null ? src.length : 0;
        boolean hasNonDefaults = false;
        int i;
        F filter;
        //遍历需要筛选的src,动态广播是BroadcastFilter,静态广播是Pair
        for (i=0; i<N && (filter=src[i]) != null; i++) {
            int match;
            if (debug) Slog.v(TAG, "Matching against filter " + filter);
            if (excludingStopped) {
                //1. 静态广播的mComponentResolver.mReceivers是继承于ActivityIntentResolver的
                // 其调用ComponentResolver.isFilterStopped会针对非系统应用判断是否stop停止的应用
                // 主要代码是!ps.isSystem() && ps.getStopped(userId);,这里就不扩展讲了
                //2. 非静态广播mReceiverResolver是new IntentResolver,直接返回false
                if (isFilterStopped(filter, userId)) {
                    if (debug) {
                        Slog.v(TAG, "  Filter's target is stopped; skipping");
                    }
                    continue;
                }
            }
            // Is delivery being limited to filters owned by a particular package?
            //这里是当intent发送给特定包的时候,判断是否当前filter
            if (packageName != null && !isPackageForFilter(packageName, filter)) {
                if (debug) {
                    Slog.v(TAG, "  Filter is not from package " + packageName + "; skipping");
                }
                continue;
            }

            // Are we verified ?
            //获取filter,动态的是BroadcastFilter,静态的是ParsedIntentInfo
            IntentFilter intentFilter = getIntentFilter(filter);
            //查看是否带有STATE_VERIFY_AUTO,这里只是打印日志
            if (intentFilter.getAutoVerify()) {
                if (localVerificationLOGV || debug) {
                    Slog.v(TAG, "  Filter verified: " + isFilterVerified(filter));
                    int authorities = intentFilter.countDataAuthorities();
                    for (int z = 0; z < authorities; z++) {
                        Slog.v(TAG, "   " + intentFilter.getDataAuthority(z)
                                .getHost());
                    }
                }
            }

            // Do we already have this one?
            //如果在dest中添加过一样的,则不在添加,跳过
            if (!allowFilterResult(filter, dest)) {
                if (debug) {
                    Slog.v(TAG, "  Filter's target already added");
                }
                continue;
            }

            //判断过滤器是否匹配
            match = intentFilter.match(action, resolvedType, scheme, data, categories, TAG);
            if (match >= 0) {
                if (debug) Slog.v(TAG, "  Filter matched!  match=0x" +
                        Integer.toHexString(match) + " hasDefault="
                        + intentFilter.hasCategory(Intent.CATEGORY_DEFAULT));
                // 对于接收者receiver来说:
                // 动态注册者mReceiverResolver.queryIntent的时候传入的defaultOnly=false
                // 静态注册者查询时需要设置了MATCH_DEFAULT_ONLY才会将defaultOnly设置成true,
                // 默认AMS收集静态注册者的时候是没有设置这个flag的,于是defaultOnly都是false
                if (!defaultOnly || intentFilter.hasCategory(Intent.CATEGORY_DEFAULT)) {
                    final R oneResult = newResult(filter, match, userId);
                    if (debug) Slog.v(TAG, "    Created result: " + oneResult);
                    if (oneResult != null) {
                        //将匹配的filter生成的结果放入dest中
                        dest.add(oneResult);
                        if (debug) {
                            dumpFilter(logPrintWriter, "    ", filter);
                            logPrintWriter.flush();
                            intentFilter.dump(logPrinter, "    ");
                        }
                    }
                } else {
                    hasNonDefaults = true;
                }
            }
        //...
    }

3.8 非oder的平行广播的入队与分发

如果没有设置ordered(也称之为serialized)按顺序,则针对动态注册类型的广播会一次性全部发送出去,
于是我们可以看到类似这样的日志:“Enqueueing parallel broadcas ***”,
这种无需等待APP的执行,很快系统就处理完了

        //是否拥FLAG_RECEIVER_REPLACE_PENDING,这类广播会将旧的广播给覆盖替换掉
        final boolean replacePending =
                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;

        //replacePending也在调试开关下输出一下日志
        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing broadcast: " + intent.getAction()
                + " replacePending=" + replacePending);
        //动态注册查询的时候没有传入broadcastAllowList(允许接收的uid列表)
        //此处会根据broadcastAllowList(不为null才会过滤)来进行动态注册接收者的过滤
        if (registeredReceivers != null && broadcastAllowList != null) {
            // if a uid whitelist was provided, remove anything in the application space that wasn't
            // in it.
            for (int i = registeredReceivers.size() - 1; i >= 0; i--) {
                final int owningAppId = UserHandle.getAppId(registeredReceivers.get(i).owningUid);
                if (owningAppId >= Process.FIRST_APPLICATION_UID
                        && Arrays.binarySearch(broadcastAllowList, owningAppId) < 0) {
                    registeredReceivers.remove(i);
                }
            }
        }

        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
        //先处理动态注册接收者的逻辑,如果该广播是非ordered(也就是无序广播),则进入里面
        if (!ordered && NR > 0) {
            // If we are not serializing this broadcast, then send the
            // registered receivers separately so they don't wait for the
            // components to be launched.
            if (isCallerSystem) {
                checkBroadcastFromSystem(intent, callerApp, callerPackage, callingUid,
                        isProtectedBroadcast, registeredReceivers);
            }
            //根据意图的flag是否有FLAG_RECEIVER_FOREGROUND来选择前台还是后台广播
            final BroadcastQueue queue = broadcastQueueForIntent(intent);

            //只有ACTION_PRE_BOOT_COMPLETED timeoutExempt才会为true
            //这里新建的BroadcastRecord r是动态广播注册者的广播记录对象
            //这里将registeredReceivers动态接受者全部传入
            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, callerPackage,
                    callerFeatureId, callingPid, callingUid, callerInstantApp, resolvedType,
                    requiredPermissions, excludedPermissions, appOp, brOptions, registeredReceivers,
                    resultTo, resultCode, resultData, resultExtras, ordered, sticky, false, userId,
                    allowBackgroundActivityStarts, backgroundActivityStartsToken,
                    timeoutExempt);
            // 由于是非order的,将这个广播的平行接收者放入队列中(动态注册的广播registeredReceivers)
            // 这就是所谓的平行广播的发送,发送后无需等待,一次性全部发完
            if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing parallel broadcast " + r);
            //设置了flag FLAG_RECEIVER_REPLACE_PENDING的广播,会替换掉BroadcastQueue旧的广播
            final boolean replaced = replacePending
                    && (queue.replaceParallelBroadcastLocked(r) != null);
            // Note: We assume resultTo is null for non-ordered broadcasts.
            //如果是普通的广播,非替换的的情况
            if (!replaced) {
                //则将该BroadcastRecord放入BroadcastQueue的mParallelBroadcasts平行广播列表中
                queue.enqueueParallelBroadcastLocked(r);
                //BroadcastQueue进行广播的正常分发
                queue.scheduleBroadcastsLocked();
            }
            //清空动态接收者,已经处理过了
            registeredReceivers = null;
            NR = 0;
        }

3.8 order广播接收者的过滤

=> 如果设置ordered(也称之为serialized)按顺序,不管是动态还是静态的注册者都是放入order的广播里面发送
=> 如果没有设置ordered,则只放入静态接收者。(普通的广播会有2个队列发送,一个是parallel broadcast,一个是ordered broadcast)
=> 最终不管是静态还是动态注册的广播,只要是需要order发送的都会合并到receivers中,排序是按照优先级(android:order/IntentFilter.setPriority设置的优先级)

广播发送时看到类似这样的日志:“Enqueueing ordered broadcast ***”,
需要按顺序执行,前面一个接收者执行完成后才能让后面的继续执行,同时前面的可以中断后面接收者的执行

        // Merge into one list.
        int ir = 0;
        //处理静态接收者
        if (receivers != null) {
            // A special case for PACKAGE_ADDED: do not allow the package
            // being added to see this broadcast.  This prevents them from
            // using this as a back door to get run as soon as they are
            // installed.  Maybe in the future we want to have a special install
            // broadcast or such for apps, but we'd like to deliberately make
            // this decision.
            String skipPackages[] = null;
            //针对ACTION_PACKAGE_ADDED/ACTION_PACKAGE_RESTARTED/ACTION_PACKAGE_DATA_CLEARED
            //这类广播不允许被安装的package接收(自己接收自己安装的广播不允许),防止自启
            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
                Uri data = intent.getData();
                if (data != null) {
                    String pkgName = data.getSchemeSpecificPart();
                    if (pkgName != null) {
                        skipPackages = new String[] { pkgName };
                    }
                }
            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
            }

            //将跳过的packageName从receivers中移除
            if (skipPackages != null && (skipPackages.length > 0)) {
                for (String skipPackage : skipPackages) {
                    if (skipPackage != null) {
                        int NT = receivers.size();
                        for (int it=0; it<NT; it++) {
                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
                            if (curt.activityInfo.packageName.equals(skipPackage)) {
                                receivers.remove(it);
                                it--;
                                NT--;
                            }
                        }
                    }
                }
            }

            //NT是静态接收者的个数,NR是动态接收者的个数
            int NT = receivers != null ? receivers.size() : 0;
            int it = 0;
            ResolveInfo curt = null;
            BroadcastFilter curr = null;
            // 遍历静态接收者receivers和动态接收者registeredReceivers
            // ir < NR代表还是存在动态接收者,由于非order的动态接收者上面已经发送完成,
            // 那么这里只会是order的广播的动态接收者
            while (it < NT && ir < NR) {
                //取出第it个静态接收者curt
                if (curt == null) {
                    curt = (ResolveInfo)receivers.get(it);
                }
                //取出ir个动态接收者curr
                if (curr == null) {
                    curr = registeredReceivers.get(ir);
                }

                //动态接收者的优先级是存放在IntentFilter的mPriority, 通过IntentFilter的setPriority设置
                //静态接收者的优先级是存放在ResolveInfo的priority,通过android:priority设置
                if (curr.getPriority() >= curt.priority) {
                    // Insert this broadcast record into the final list.
                    // 如果动态接收者curr的优先级大于静态接收者curt的优先级,
                    // 则将动态接收者curr放入原来静态接收者(curt)it的位置,
                    // 在这之前静态接收者(curt)it已经取出来了,这里只是用动态接收者curr来填充it的位置
                    receivers.add(it, curr);
                    //动态接收者用过了则ir++, 而且将curr = null置为空,再次取下一个动态接收者
                    //当前receivers it的位置存放动态接收者curr
                    ir++;
                    curr = null;
                    //同时这里使用了list add的特性,当一个元素增加到it时,其从it到NT的元素自动+1
                    //于是下一个元素就是it++
                    it++;
                    //receivers新增了一个元素,于是总大小NT++
                    NT++;
                } else {
                    // Skip to the next ResolveInfo in the final list.
                    //否则静态接收者curt的it++,同时curt = null,再次取下一个静态接收者
                    //当前receivers it的位置存放静态接收者curt
                    it++;
                    curt = null;
                }
            }
        }

        // 如果动态接收者还没有遍历完,说明最新的ir动态接收者curr的
        // 优先级小于receivers最后一个静态接收者curt的优先级,
        // 则将剩下的registeredReceivers全部加入到receivers的尾部
        while (ir < NR) {
            if (receivers == null) {
                receivers = new ArrayList();
            }
            receivers.add(registeredReceivers.get(ir));
            ir++;
        }

        //isCallerSystem(前面有解释)是否系统调用发送广播
        if (isCallerSystem) {
            //查看一下发送的是否保护的广播
            checkBroadcastFromSystem(intent, callerApp, callerPackage, callingUid,
                    isProtectedBroadcast, receivers);
        }

        if ((receivers != null && receivers.size() > 0)
                || resultTo != null) {
            //根据意图的flag是否有FLAG_RECEIVER_FOREGROUND来选择前台还是后台广播
            BroadcastQueue queue = broadcastQueueForIntent(intent);

            // 构建有序的BroadcastRecord,如果ordered = true则包含静态和动态接收者,
            // 如果ordered = false则只包含静态接收者,由于静态接收者都是有序发送的,
            // 故其实这个receivers全部都是有序接收的接收者
            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp, callerPackage,
                    callerFeatureId, callingPid, callingUid, callerInstantApp, resolvedType,
                    requiredPermissions, excludedPermissions, appOp, brOptions,
                    receivers, resultTo, resultCode, resultData, resultExtras,
                    ordered, sticky, false, userId, allowBackgroundActivityStarts,
                    backgroundActivityStartsToken, timeoutExempt);

            //静态注册的广播在receivers中,发送ordered 按顺序接收广播
            if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing ordered broadcast " + r);

            //设置了flag FLAG_RECEIVER_REPLACE_PENDING的广播,会替换掉BroadcastQueue旧的广播
            final BroadcastRecord oldRecord =
                    replacePending ? queue.replaceOrderedBroadcastLocked(r) : null;

            if (oldRecord != null) {
                // Replaced, fire the result-to receiver.
                //存在旧的oldRecord(有序的),而且resultTo不为null
                if (oldRecord.resultTo != null) {
                    final BroadcastQueue oldQueue = broadcastQueueForIntent(oldRecord.intent);
                    try {
                        //则告诉原来的调用者oldRecord.callerApp,这个广播已经给cancel掉了
                        oldQueue.performReceiveLocked(oldRecord.callerApp, oldRecord.resultTo,
                                oldRecord.intent,
                                Activity.RESULT_CANCELED, null, null,
                                false, false, oldRecord.userId);
                    } catch (RemoteException e) {
                        Slog.w(TAG, "Failure ["
                                + queue.mQueueName + "] sending broadcast result of "
                                + intent, e);

                    }
                }
            } else {
                //将order的广播放入mDispatcher的mOrderedBroadcasts中去
                queue.enqueueOrderedBroadcastLocked(r);
                queue.scheduleBroadcastsLocked();
            }
        } else {
            // There was nobody interested in the broadcast, but we still want to record
            // that it happened.
            // 如果接收者receivers为null,而且resultTo也是null,则到这里已经没有人关注
            // 如果不是发送给特定的包或者组件,而且不是只发送给动态注册的广播
            if (intent.getComponent() == null && intent.getPackage() == null
                    && (intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
                // This was an implicit broadcast... let's record it for posterity.
                // 则记录一下这个广播的信息
                addBroadcastStatLocked(intent.getAction(), callerPackage, 0, 0, 0);
            }
        }

        //返回成功发送
        return ActivityManager.BROADCAST_SUCCESS;
    }

4. 广播队列的处理

前面讲的是过滤接收者,然后将信息放入广播队列中,那么广播队列是如何处理这类信息的呢?

这一节我们接下去讲解广播队列处理流程

4.1 新建广播队列

目前有3个广播队列,一个是前台、一个是后台、一个是Offload的广播队列
其中前台广播超时时间是10s,后台是60s,Offload的广播也是60s

//ActivityManagerService.java
    //前台广播队列
    final BroadcastQueue mFgBroadcastQueue;
    //后台广播队列
    final BroadcastQueue mBgBroadcastQueue;
    //Offload的广播队列(默认这个没有使用)
    final BroadcastQueue mOffloadBroadcastQueue;
    // Convenient for easy iteration over the queues. Foreground is first
    // so that dispatch of foreground broadcasts gets precedence.
	//总的广播队列
    final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[3];


    public ActivityManagerService(Context systemContext, ActivityTaskManagerService atm) {
        //...
        // Broadcast policy parameters
        final BroadcastConstants foreConstants = new BroadcastConstants(
                Settings.Global.BROADCAST_FG_CONSTANTS);
        //前台广播超时时间是10s
        foreConstants.TIMEOUT = BROADCAST_FG_TIMEOUT;

        final BroadcastConstants backConstants = new BroadcastConstants(
                Settings.Global.BROADCAST_BG_CONSTANTS);
        //后台广播超时时间是60s
        backConstants.TIMEOUT = BROADCAST_BG_TIMEOUT;

        final BroadcastConstants offloadConstants = new BroadcastConstants(
                Settings.Global.BROADCAST_OFFLOAD_CONSTANTS);
        offloadConstants.TIMEOUT = BROADCAST_BG_TIMEOUT;
        // by default, no "slow" policy in this queue
		//没有SLOW_TIME,不使用延迟策略广播
        offloadConstants.SLOW_TIME = Integer.MAX_VALUE;

		//默认是没有使用Offload的广播的
        mEnableOffloadQueue = SystemProperties.getBoolean(
                "persist.device_config.activity_manager_native_boot.offload_queue_enabled", false);

		//这里的mHandler是AMS的MainHandler,优先级是THREAD_PRIORITY_FOREGROUND前台
        mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
                "foreground", foreConstants, false);
        mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
                "background", backConstants, true);
        mOffloadBroadcastQueue = new BroadcastQueue(this, mHandler,
                "offload", offloadConstants, true);
        mBroadcastQueues[0] = mFgBroadcastQueue;
        mBroadcastQueues[1] = mBgBroadcastQueue;
        mBroadcastQueues[2] = mOffloadBroadcastQueue;

		//...
    }

4.2 广播接收者入队列

  1. 平行广播接收者enqueueParallelBroadcastLocked入队列

这里入队列就是全部丢入广播队列BroadcastQueue的mParallelBroadcasts中

//BroadcastQueue.java
    public void enqueueParallelBroadcastLocked(BroadcastRecord r) {
        mParallelBroadcasts.add(r);
        enqueueBroadcastHelper(r);
    }
  1. order广播接收者enqueueOrderedBroadcastLocked入队列

这里多了一个中转mDispatcher(BroadcastDispatcher),放入的其实是BroadcastDispatcher的mOrderedBroadcasts中

//BroadcastQueue.java
    public void enqueueOrderedBroadcastLocked(BroadcastRecord r) {
        mDispatcher.enqueueOrderedBroadcastLocked(r);
        enqueueBroadcastHelper(r);
    }

//BroadcastDispatcher.java
    void enqueueOrderedBroadcastLocked(BroadcastRecord r) {
        mOrderedBroadcasts.add(r);
    }

4.3 广播队列的分发

一般外部调用(非BroadcastQueue中)分发有2种
1、scheduleBroadcastsLocked 让广播队列开始调度分发广播。如:发送广播的时候,平行广播分发、order广播分发使用的方式;注册的时候发送粘性广播也是使用这个方式
2、processNextBroadcastLocked 直接处理下一个广播。如:order广播中上一个广播处理完成后(这个比较常见,一会也会讲)、unregister的时候

  1. scheduleBroadcastsLocked让广播队列开始调度分发广播
    调用这个函数需要加入AMS的锁,也就是Thread.holdsLock(mService)需要返回true(原生调用都是包含这个锁的,注意新增的调用)

scheduleBroadcastsLocked通过mHandler发送BROADCAST_INTENT_MSG -> processNextBroadcast(true)开始处理下一个广播分发

//BroadcastQueue.java
    public void scheduleBroadcastsLocked() {
        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Schedule broadcasts ["
                + mQueueName + "]: current="
                + mBroadcastsScheduled);
		//是否mBroadcastsScheduled正在调度中,调度中则先返回,如果出现广播堆积优先查看这个值是否一直等于true
        if (mBroadcastsScheduled) {
            return;
        }
		//通过mHandler(其looper和AMS的MainHandler是一个looper)发送BROADCAST_INTENT_MSG
        mHandler.sendMessage(mHandler.obtainMessage(BROADCAST_INTENT_MSG, this));
        mBroadcastsScheduled = true;
    }

    private final class BroadcastHandler extends Handler {
        public BroadcastHandler(Looper looper) {
            super(looper, null, true);
        }

        @Override
        public void handleMessage(Message msg) {
            switch (msg.what) {
                case BROADCAST_INTENT_MSG: {
                    if (DEBUG_BROADCAST) Slog.v(
                            TAG_BROADCAST, "Received BROADCAST_INTENT_MSG ["
                                    + mQueueName + "]");
					//开始下一个广播的处理,传入的fromMsg是true
                    processNextBroadcast(true);
                } break;
                case BROADCAST_TIMEOUT_MSG: {
                    synchronized (mService) {
                        //广播超时的处理
                        broadcastTimeoutLocked(true);
                    }
                } break;
            }
        }
    }

	//注意从handler的持有mService的锁
    private void processNextBroadcast(boolean fromMsg) {
        synchronized (mService) {
            //此处skipOomAdj是false,也就是需要调整OomAdj
            processNextBroadcastLocked(fromMsg, false);
        }
    }

4.4 处理分发下一个广播

processNextBroadcastLocked下一个广播分发

4.4.1 mParallelBroadcasts平行广播的分发

  1. mParallelBroadcasts平行广播是一次性全部丢出去的,通过deliverToRegisteredReceiverLocked来分发到动态接收者
    //分发下一个广播
    //fromMsg:是否从handleMessage(BROADCAST_INTENT_MSG)而来
    //skipOomAdj:是否需要跳过adj调整,AMS的unregisterReceiver、finishReceiver过来是true,
    //BroadcastQueue过来是false
    final void processNextBroadcastLocked(boolean fromMsg, boolean skipOomAdj) {
        //BroadcastRecord广播的记录者,需要分发的广播
        BroadcastRecord r;

        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "processNextBroadcast ["
                + mQueueName + "]: "
                + mParallelBroadcasts.size() + " parallel broadcasts; "
                + mDispatcher.describeStateLocked());

        //更新mProcessCpuMutexFree,可以继续执行updateCpuStatsNow
        mService.updateCpuStats();

        //如果fromMsg == ture,则设置mBroadcastsScheduled为true,允许scheduleBroadcastsLocked下一个BROADCAST_INTENT_MSG
        //注意原生逻辑scheduleBroadcastsLocked和processNextBroadcastLocked都持有AMS的锁,不然mBroadcastsScheduled会出现线程冲突导致广播堆积
        if (fromMsg) {
            mBroadcastsScheduled = false;
        }

        // First, deliver any non-serialized broadcasts right away.
        //第一步:先分发mParallelBroadcasts平行的广播队列
        while (mParallelBroadcasts.size() > 0) {
            //取出平行广播队列里面的第一个BroadcastRecord
            r = mParallelBroadcasts.remove(0);
            //设置BroadcastRecord r广播分发时间dispatchTime
            r.dispatchTime = SystemClock.uptimeMillis();
            //System.currentTimeMillis()获取的是系统时钟的时间,修改系统时间这个时间会变化
            r.dispatchClockTime = System.currentTimeMillis();

            //如果打开了"am"的tag会记录trace的日志
            //"am",         "Activity Manager",         ATRACE_TAG_ACTIVITY_MANAGER,
            if (Trace.isTagEnabled(Trace.TRACE_TAG_ACTIVITY_MANAGER)) {
                //结束DELIVERY_PENDING的trace
                Trace.asyncTraceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER,
                        createBroadcastTraceTitle(r, BroadcastRecord.DELIVERY_PENDING),
                        System.identityHashCode(r));
                //开始DELIVERY_DELIVERED的trace
                Trace.asyncTraceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER,
                        createBroadcastTraceTitle(r, BroadcastRecord.DELIVERY_DELIVERED),
                        System.identityHashCode(r));
            }

            final int N = r.receivers.size();
            if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG_BROADCAST, "Processing parallel broadcast ["
                    + mQueueName + "] " + r);
            //遍历构建 BroadcastRecord 的所有receivers
            for (int i=0; i<N; i++) {
                Object target = r.receivers.get(i);
                if (DEBUG_BROADCAST)  Slog.v(TAG_BROADCAST,
                        "Delivering non-ordered on [" + mQueueName + "] to registered "
                                + target + ": " + r);
                deliverToRegisteredReceiverLocked(r,
                        (BroadcastFilter) target, false, i);
            }
            addBroadcastToHistoryLocked(r);
            if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG_BROADCAST, "Done with parallel broadcast ["
                    + mQueueName + "] " + r);
        }
```java

2) deliverToRegisteredReceiverLocked分发到动态接收者

deliverToRegisteredReceiverLocked -> performReceiveLocked


```java
    private void deliverToRegisteredReceiverLocked(BroadcastRecord r,
                                                   BroadcastFilter filter, boolean ordered, int index) {
        //...
		//前面是各类跳过skip的场景

        r.delivery[index] = BroadcastRecord.DELIVERY_DELIVERED;

        // If this is not being sent as an ordered broadcast, then we
        // don't want to touch the fields that keep track of the current
        // state of ordered broadcasts.
        if (ordered) {
            //order分发的时候,会有r.receiver的设置
            r.receiver = filter.receiverList.receiver.asBinder();
            r.curFilter = filter;
            filter.receiverList.curBroadcast = r;
            r.state = BroadcastRecord.CALL_IN_RECEIVE;
            if (filter.receiverList.app != null) {
                // Bump hosting application to no longer be in background
                // scheduling class.  Note that we can't do that if there
                // isn't an app...  but we can only be in that case for
                // things that directly call the IActivityManager API, which
                // are already core system stuff so don't matter for this.
                r.curApp = filter.receiverList.app;
                filter.receiverList.app.mReceivers.addCurReceiver(r);
                mService.enqueueOomAdjTargetLocked(r.curApp);
                mService.updateOomAdjPendingTargetsLocked(
                        OomAdjuster.OOM_ADJ_REASON_START_RECEIVER);
            }
        } else if (filter.receiverList.app != null) {
            mService.mOomAdjuster.mCachedAppOptimizer.unfreezeTemporarily(filter.receiverList.app);
        }

        try {
            if (DEBUG_BROADCAST_LIGHT) Slog.i(TAG_BROADCAST,
                    "Delivering to " + filter + " : " + r);
            if (filter.receiverList.app != null && filter.receiverList.app.isInFullBackup()) {
                // Skip delivery if full backup in progress
                // If it's an ordered broadcast, we need to continue to the next receiver.
                //全备份的app接收这才会到这里
                if (ordered) {
                    skipReceiverLocked(r);
                }
            } else {
                //一般跑的这里
                r.receiverTime = SystemClock.uptimeMillis();
                maybeAddAllowBackgroundActivityStartsToken(filter.receiverList.app, r);
                maybeScheduleTempAllowlistLocked(filter.owningUid, r, r.options);
                //接下去运行的是performReceiveLocked
                //filter.receiverList.app是动态注册的callerApp, filter.receiverList.receiver是动态注册是传入的IIntentReceiver
                performReceiveLocked(filter.receiverList.app, filter.receiverList.receiver,
                        new Intent(r.intent), r.resultCode, r.resultData,
                        r.resultExtras, r.ordered, r.initialSticky, r.userId);
                // parallel broadcasts are fire-and-forget, not bookended by a call to
                // finishReceiverLocked(), so we manage their activity-start token here
                if (filter.receiverList.app != null
                        && r.allowBackgroundActivityStarts && !r.ordered) {
                    postActivityStartTokenRemoval(filter.receiverList.app, r);
                }
            }
            if (ordered) {
                r.state = BroadcastRecord.CALL_DONE_RECEIVE;
            }
        } catch (RemoteException e) {
            Slog.w(TAG, "Failure sending broadcast " + r.intent, e);
            // Clean up ProcessRecord state related to this broadcast attempt
            if (filter.receiverList.app != null) {
                filter.receiverList.app.removeAllowBackgroundActivityStartsToken(r);
                if (ordered) {
                    filter.receiverList.app.mReceivers.removeCurReceiver(r);
                    // Something wrong, its oom adj could be downgraded, but not in a hurry.
                    mService.enqueueOomAdjTargetLocked(r.curApp);
                }
            }
            // And BroadcastRecord state related to ordered delivery, if appropriate
            if (ordered) {
                //异常还原
                r.receiver = null;
                r.curFilter = null;
                filter.receiverList.curBroadcast = null;
            }
        }
    }

  1. performReceiveLocked返回结果给动态接收者

performReceiveLocked返回结果给动态接收者(该函数还在广播发送时用于结果返回)


    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) {
            final IApplicationThread thread = app.getThread();
            if (thread != null) {
                // If we have an app thread, do the call through that so it is
                // correctly ordered with other one-way calls.
                try {
                    //调用app进程的scheduleRegisteredReceiver,分发到app进程
                    //scheduleRegisteredReceiver包括: updateProcessState进程状态更新/receiver.performReceive执行
                    //receiver调用的是LoadedApk.ReceiverDispatcher的performReceive -> mActivityThread.post一般是主线成去分发广播
                    thread.scheduleRegisteredReceiver(receiver, intent, resultCode,
                            data, extras, ordered, sticky, sendingUser,
                            app.mState.getReportedProcState());
                    // TODO: Uncomment this when (b/28322359) is fixed and we aren't getting
                    // DeadObjectException when the process isn't actually dead.
                    //} catch (DeadObjectException ex) {
                    // Failed to call into the process.  It's dying so just let it die and move on.
                    //    throw ex;
                } 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.getPid() + "). Crashing it.");
                        app.scheduleCrashLocked("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
            receiver.performReceive(intent, resultCode, data, extras, ordered,
                    sticky, sendingUser);
        }
    }
  1. ActivityThread.java的scheduleRegisteredReceiver(这里已经是app线程了)

IIntentReceiver在之前的文章“Android S动态广播注册流程”里面已经提到是:LoadedApk.ReceiverDispatcher得到mIIntentReceiver

//ActivityThread.java
        public void scheduleRegisteredReceiver(IIntentReceiver receiver, Intent intent,
                int resultCode, String dataStr, Bundle extras, boolean ordered,
                boolean sticky, int sendingUser, int processState) throws RemoteException {
            //更新app的进程状态processState
            updateProcessState(processState, false);
			//调用IIntentReceiver的performReceive发送广播
            receiver.performReceive(intent, resultCode, dataStr, extras, ordered,
                    sticky, sendingUser);
        }

//LoadedApk.java
//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) {
                    Log.wtf(TAG, "Null intent received");
                    rd = null;
                } else {
                    //mDispatcher是ReceiverDispatcher
                    rd = mDispatcher.get();
                }
                if (ActivityThread.DEBUG_BROADCAST) {
                    int seq = intent.getIntExtra("seq", -1);
                    Slog.i(ActivityThread.TAG, "Receiving broadcast " + intent.getAction()
                            + " seq=" + seq + " to " + (rd != null ? rd.mReceiver : null));
                }
                if (rd != null) {
                    //一般执行的是这里LoadedApk.ReceiverDispatcher的performReceive
                    rd.performReceive(intent, resultCode, data, extras,
                            ordered, sticky, sendingUser);
                } else {
                    // The activity manager dispatched a broadcast to a registered
                    // receiver in this process, but before it could be delivered the
                    // receiver was unregistered.  Acknowledge the broadcast on its
                    // behalf so that the system's broadcast sequence can continue.
                    if (ActivityThread.DEBUG_BROADCAST) Slog.i(ActivityThread.TAG,
                            "Finishing broadcast to unregistered receiver");
                    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) {
                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);
                }
            }
			
			//这里是通过mActivityThread线程(一般是app主线程,也可以自己传入Handler scheduler当做调度线程)
			//实际是在调度线程中运行new Args的run方法
            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);
                }
            }
        }
  1. app动态注册的BroadcastReceiver接收与返回结果

=> BroadcastReceiver的onReceive执行
=> 处理完成后,调用AMS的finishReceiver,告诉系统该接受者已经处理完了

//LoadedApk.java
        final class Args extends BroadcastReceiver.PendingResult {
            private Intent mCurIntent;
            private final boolean mOrdered;
            private boolean mDispatched;
            private boolean mRunCalled;

            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 final Runnable getRunnable() {
                return () -> {
                    final BroadcastReceiver receiver = mReceiver;
                    final boolean ordered = mOrdered;

                    if (ActivityThread.DEBUG_BROADCAST) {
                        int seq = mCurIntent.getIntExtra("seq", -1);
                        Slog.i(ActivityThread.TAG, "Dispatching broadcast " + mCurIntent.getAction()
                                + " seq=" + seq + " to " + mReceiver);
                        Slog.i(ActivityThread.TAG, "  mRegistered=" + mRegistered
                                + " mOrderedHint=" + ordered);
                    }

                    final IActivityManager mgr = ActivityManager.getService();
                    final Intent intent = mCurIntent;
                    if (intent == null) {
                        Log.wtf(TAG, "Null intent being dispatched, mDispatched=" + mDispatched
                                + (mRunCalled ? ", run() has already been called" : ""));
                    }

                    mCurIntent = null;
                    mDispatched = true;
                    mRunCalled = true;
                    if (receiver == null || intent == null || mForgotten) {
                        if (mRegistered && ordered) {
                            if (ActivityThread.DEBUG_BROADCAST) Slog.i(ActivityThread.TAG,
                                    "Finishing null broadcast to " + mReceiver);
                            sendFinished(mgr);
                        }
                        return;
                    }

                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "broadcastReceiveReg");
                    try {
                        ClassLoader cl = mReceiver.getClass().getClassLoader();
                        intent.setExtrasClassLoader(cl);
                        // TODO: determine at registration time if caller is
                        // protecting themselves with signature permission
                        intent.prepareToEnterProcess(ActivityThread.isProtectedBroadcast(intent),
                                mContext.getAttributionSource());
                        setExtrasClassLoader(cl);
                        receiver.setPendingResult(this);
						//这里就是调用BroadcastReceiver的onReceive方法了
						//如之前例子中,此时会输出"MyReceiver dynamic intent = android.intent.action.SCREEN_ON"
                        receiver.onReceive(mContext, intent);
                    } catch (Exception e) {
                        if (mRegistered && ordered) {
                            if (ActivityThread.DEBUG_BROADCAST) Slog.i(ActivityThread.TAG,
                                    "Finishing failed broadcast to " + mReceiver);
                            sendFinished(mgr);
                        }
                        if (mInstrumentation == null ||
                                !mInstrumentation.onException(mReceiver, e)) {
                            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
                            throw new RuntimeException(
                                    "Error receiving broadcast " + intent
                                            + " in " + mReceiver, e);
                        }
                    }

                    if (receiver.getPendingResult() != null) {
                        //结束这个接收者的广播分发,finish(BroadcastReceiver.java)->
                        finish();
                    }
                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
                };
            }
        }

//BroadcastReceiver.java
        public final void finish() {
            if (mType == TYPE_COMPONENT) {
                final IActivityManager mgr = ActivityManager.getService();
                if (QueuedWork.hasPendingWork()) {
                    // If this is a broadcast component, we need to make sure any
                    // queued work is complete before telling AM we are done, so
                    // we don't have our process killed before that.  We now know
                    // there is pending work; put another piece of work at the end
                    // of the list to finish the broadcast, so we don't block this
                    // thread (which may be the main thread) to have it finished.
                    //
                    // Note that we don't need to use QueuedWork.addFinisher() with the
                    // runnable, since we know the AM is waiting for us until the
                    // executor gets to it.
                    QueuedWork.queue(new Runnable() {
                        @Override public void run() {
                            if (ActivityThread.DEBUG_BROADCAST) Slog.i(ActivityThread.TAG,
                                    "Finishing broadcast after work to component " + mToken);
                            sendFinished(mgr);
                        }
                    }, false);
                } else {
                    if (ActivityThread.DEBUG_BROADCAST) Slog.i(ActivityThread.TAG,
                            "Finishing broadcast to component " + mToken);
					//发送给静态组件后返回AMS的情况
                    sendFinished(mgr);
                }
            } else if (mOrderedHint && mType != TYPE_UNREGISTERED) {
                if (ActivityThread.DEBUG_BROADCAST) Slog.i(ActivityThread.TAG,
                        "Finishing broadcast to " + mToken);
                final IActivityManager mgr = ActivityManager.getService();
				//发送给动态接收者后返回AMS的情况,非order的是没有结果返回的
                sendFinished(mgr);
            }
        }

       //完成接收处理后app返回AMS
       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) {
                        //order的调用的多了mResultCode、mResultData、mResultExtras、
						//mAbortBroadcast(是否中断后续接收者,app使用abortBroadcast设置)
						//包含静态和动态接收者
                        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.
						//非order的情况,这里只会是组件接收的时候返回
                        am.finishReceiver(mToken, 0, null, null, false, mFlags);
                    }
                } catch (RemoteException ex) {
                }
            }
        }

4.4.2 mPendingBroadcast挂起广播的处理

mPendingBroadcast是正在处理的有序队列中的广播,由于进程没有启动,先挂起了。
Need to start app 的时候会设置mPendingBroadcast = r

需要先把mPendingBroadcast处理完成才能处理下一个有序队列中的广播

        // Now take care of the next serialized one...

        // If we are waiting for a process to come up to handle the next
        // broadcast, then do nothing at this point.  Just in case, we
        // check that the process we're waiting for still exists.
        // 分析是建议打开日志 DEBUG_BROADCAST DEBUG_BROADCAST_BACKGROUND DEBUG_BROADCAST_DEFERRAL DEBUG_BROADCAST_LIGHT
        // 至于DEBUG_ALL也可以考虑打开
        // Need to start app 的时候会设置mPendingBroadcast = r;
        // 1. 如果进程没有启动,则首先启动进程startProcessLocked(am_proc_start)
        // 2. 并将这个广播放入mPendingBroadcast中去,同时mPendingBroadcast.curApp = 下一个处理广播的进程
        // 3. 当进程启动而且进行attachApplicationLocked(AMS)(am_proc_bound)/bindApplication的时候
        // 调用attachApplicationLocked(AMS)->sendPendingBroadcastsLocked->processCurBroadcastLocked将该广播传递给curApp-> scheduleReceiver(ActivityThread)
        // 此时也会清除mPendingBroadcast = null,代表已经处理过了
        // 4. 当广播处理完成后会从app回传AMS
        // 动态注册完成广播LoadedApk.ReceiverDispatcher.Args -> mActivityThread.post(args.getRunnable()) -> finish(BroadcastReceiver.java)
        // deliverToRegisteredReceiverLocked/performReceiveLocked -> app.thread.scheduleRegisteredReceiver -> receiver.performReceive
        // -> mActivityThread.post(args.getRunnable()) -> finish(BroadcastReceiver.java)
        // 静态注册完成广播 scheduleReceiver(ActivityThread) -> RECEIVER
        // -> handleReceiver(ActivityThread.java) -> finish(BroadcastReceiver.java)
        // => finish/sendFinished(BroadcastReceiver.java) -> am.finishReceiver
        // 5. ams收到curApp将广播处理完成,则调用r.queue.processNextBroadcastLocked继续处理下一个广播
        // finishReceiver(AMS) -> r.queue.processNextBroadcastLocked(BroadcastQueue)
        if (mPendingBroadcast != null) {
            if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG_BROADCAST,
                    "processNextBroadcast [" + mQueueName + "]: waiting for "
                            + mPendingBroadcast.curApp);

            boolean isDead;
            //是否存在这个进程的pid
            if (mPendingBroadcast.curApp.getPid() > 0) {
                synchronized (mService.mPidsSelfLocked) {
                    //如果存在pid,则从mPidsSelfLocked中获取这个进程的ProcessRecord proc
                    ProcessRecord proc = mService.mPidsSelfLocked.get(
                            mPendingBroadcast.curApp.getPid());
                    //如果proc存在,而且没有发生crash,则isDead = false
                    isDead = proc == null || proc.mErrorState.isCrashing();
                }
            } else {
                //否则从mProcessList通过名字获取该进程的ProcessRecord proc
                final ProcessRecord proc = mService.mProcessList.getProcessNamesLOSP().get(
                        mPendingBroadcast.curApp.processName, mPendingBroadcast.curApp.uid);
                //如果proc存在,而且该进程正在启动中isPendingStart,则isDead = false
                isDead = proc == null || !proc.isPendingStart();
            }
            if (!isDead) {
                // It's still alive, so keep waiting
                //如果mPendingBroadcast还存在,则直接返回,等待其先处理
                //注意,这里等待mPendingBroadcast处理了才会有下一个广播的处理,不然一直再此等待
                return;
            } else {
                //如果app死掉了
                Slog.w(TAG, "pending app  ["
                        + mQueueName + "]" + mPendingBroadcast.curApp
                        + " died before responding to broadcast");
                mPendingBroadcast.state = BroadcastRecord.IDLE;
                //下一次处理这个BroadcastRecord的nextReceiver还是这个recIdx
                mPendingBroadcast.nextReceiver = mPendingBroadcastRecvIndex;
                //app死掉了清除mPendingBroadcast = null, 跳过这个mPendingBroadcast
                mPendingBroadcast = null;
            }
        }

4.4.3 取出下一个有序队列中的广播

  1. 主要是通过mDispatcher的getNextBroadcastLocked来取出有序广播队列的广播(这里就只讲解其中的mOrderedBroadcasts,如我们上面有序广播放入的地方)

  2. 总的分发时间大于210s/60snumReceivers的时间,则发出总得广播超时,并且将这个广播给finish掉

  3. 如果已经完成了广播发送,而且发送时有设置IIntentReceiver resultTo(结果返回的地方),则调用performReceiveLocked,返回结果给到resultTo

  4. 如果已经完成了广播发送,则取消该order的超时设定,输出“Finished with ordered broadcast”类似日志

        boolean looped = false;

        do {
            final long now = SystemClock.uptimeMillis();
            //取得mAlarmBroadcasts(alarm挂起的广播)、mDeferredBroadcasts(如果存在order的广播在处理,这类延迟广播会按照deferUntil进行延迟)、
            // mOrderedBroadcasts 有序广播队列,依次取出来
            r = mDispatcher.getNextBroadcastLocked(now);

            if (r == null) {
                // No more broadcasts are deliverable right now, so all done!
                //如果存在延迟的广播mDeferredBroadcasts,则重新下一次调度scheduleBroadcastsLocked
                //不过一般上面BroadcastRecord r都取得出来(存在延迟的广播mDeferredBroadcasts, getNextBroadcastLocked得出来),
                // 也就是这里相当于没啥作用
                mDispatcher.scheduleDeferralCheckLocked(false);

                synchronized (mService.mAppProfiler.mProfilerLock) {
                    //将AMS所有挂起的gc进程mProcessesToGc进行按顺序的gc
                    mService.mAppProfiler.scheduleAppGcsLPf();
                }
                if (looped && !skipOomAdj) {
                    // If we had finished the last ordered broadcast, then
                    // make sure all processes have correct oom and sched
                    // adjustments.
                    //adj调整,原因是启动了receiver
                    mService.updateOomAdjPendingTargetsLocked(
                            OomAdjuster.OOM_ADJ_REASON_START_RECEIVER);
                }

                // when we have no more ordered broadcast on this queue, stop logging
                //现在已经没有mOrderedBroadcasts 有序广播队列, 则停止log的输出mLogLatencyMetrics = false
                if (mService.mUserController.mBootCompleted && mLogLatencyMetrics) {
                    mLogLatencyMetrics = false;
                }

                //结束本次processNextBroadcastLocked
                return;
            }

            //是否需要强制结束recevie
            boolean forceReceive = false;

            // Ensure that even if something goes awry with the timeout
            // detection, we catch "hung" broadcasts here, discard them,
            // and continue to make progress.
            //
            // This is only done if the system is ready so that early-stage receivers
            // don't get executed with timeouts; and of course other timeout-
            // exempt broadcasts are ignored.
            //numReceivers接收者的个数
            int numReceivers = (r.receivers != null) ? r.receivers.size() : 0;
            //systemReady之后mService.mProcessesReady = true
            //timeoutExempt只有ACTION_PRE_BOOT_COMPLETED才会设置为true
            //r.dispatchTime是开始分发该BroadcastRecord r的时间
            if (mService.mProcessesReady && !r.timeoutExempt && r.dispatchTime > 0) {
                //如果当前时间now > r.dispatchTime + (2 * mConstants.TIMEOUT(10s/60s) * numReceivers)
                //也就是总的分发时间大于2*10s/60s*numReceivers的时间,则告知这个广播出现anr
                //isAnrDeferrable是mtk加入的是否需要跳过anr的逻辑
                if ((numReceivers > 0) &&
                        (now > r.dispatchTime + (2 * mConstants.TIMEOUT * numReceivers)) &&
                        /// M: ANR Debug Mechanism
                        !mService.mAnrManager.isAnrDeferrable()) {
                    Slog.w(TAG, "Hung broadcast ["
                            + mQueueName + "] discarded after timeout failure:"
                            + " now=" + now
                            + " dispatchTime=" + r.dispatchTime
                            + " startTime=" + r.receiverTime
                            + " intent=" + r.intent
                            + " numReceivers=" + numReceivers
                            + " nextReceiver=" + r.nextReceiver
                            + " state=" + r.state);
                    broadcastTimeoutLocked(false); // forcibly finish this broadcast
                    //设置强制结束recevie (forceReceive = true)
                    forceReceive = true;
                    r.state = BroadcastRecord.IDLE;
                }
            }

            if (r.state != BroadcastRecord.IDLE) {
                if (DEBUG_BROADCAST) Slog.d(TAG_BROADCAST,
                        "processNextBroadcast("
                                + mQueueName + ") called when not idle (state="
                                + r.state + ")");
                return;
            }

            // Is the current broadcast is done for any reason?
            // 如果没有r.receivers 或者 r.nextReceiver已经遍历完成最后一个了
            // 或者强制结束forceReceive,
            // 或者resultAbort为true(bortBroadcast(应用进程) -> finishReceiver(AMS)-> r.queue.finishReceiverLocked(BroadcastQueue))
            if (r.receivers == null || r.nextReceiver >= numReceivers
                    || r.resultAbort || forceReceive) {
                // Send the final result if requested
                //是否有resultTo,如果有将结果回传resultTo
                if (r.resultTo != null) {
                    boolean sendResult = true;

                    // if this was part of a split/deferral complex, update the refcount and only
                    // send the completion when we clear all of them
                    if (r.splitToken != 0) {
                        int newCount = mSplitRefcounts.get(r.splitToken) - 1;
                        if (newCount == 0) {
                            // done!  clear out this record's bookkeeping and deliver
                            if (DEBUG_BROADCAST_DEFERRAL) {
                                Slog.i(TAG_BROADCAST,
                                        "Sending broadcast completion for split token "
                                                + r.splitToken + " : " + r.intent.getAction());
                            }
                            mSplitRefcounts.delete(r.splitToken);
                        } else {
                            // still have some split broadcast records in flight; update refcount
                            // and hold off on the callback
                            if (DEBUG_BROADCAST_DEFERRAL) {
                                Slog.i(TAG_BROADCAST,
                                        "Result refcount now " + newCount + " for split token "
                                                + r.splitToken + " : " + r.intent.getAction()
                                                + " - not sending completion yet");
                            }
                            sendResult = false;
                            mSplitRefcounts.put(r.splitToken, newCount);
                        }
                    }
                    if (sendResult) {
                        if (r.callerApp != null) {
                            mService.mOomAdjuster.mCachedAppOptimizer.unfreezeTemporarily(
                                    r.callerApp);
                        }
                        try {
                            if (DEBUG_BROADCAST) {
                                Slog.i(TAG_BROADCAST, "Finishing broadcast [" + mQueueName + "] "
                                        + r.intent.getAction() + " app=" + r.callerApp);
                            }
                            //将结果返回给app
                            performReceiveLocked(r.callerApp, r.resultTo,
                                    new Intent(r.intent), r.resultCode,
                                    r.resultData, r.resultExtras, false, false, r.userId);
                            // Set this to null so that the reference
                            // (local and remote) isn't kept in the mBroadcastHistory.
                            r.resultTo = null;
                        } catch (RemoteException e) {
                            r.resultTo = null;
                            Slog.w(TAG, "Failure ["
                                    + mQueueName + "] sending broadcast result of "
                                    + r.intent, e);
                        }
                    }
                }

                if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Cancelling BROADCAST_TIMEOUT_MSG");
                //取消广播超时
                cancelBroadcastTimeoutLocked();

                if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG_BROADCAST,
                        "Finished with ordered broadcast " + r);

                // ... and on to the next...
                //添加到广播历史中去,代表完成了
                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);
                }

                //完成odered的广播后,在retireBroadcastLocked中设置mCurrentBroadcast = null(一般在r == mCurrentBroadcast时)
                mDispatcher.retireBroadcastLocked(r);
                //r == null继续while循环,取出下一个广播
                r = null;
                looped = true;
                continue;
            }

            // Check whether the next receiver is under deferral policy, and handle that
            // accordingly.  If the current broadcast was already part of deferred-delivery
            // tracking, we know that it must now be deliverable as-is without re-deferral.
            // addDeferredBroadcast的时候会将deferred设置成ture,
            // 如果这个广播没有进行延迟,则判断一下是否需要延迟
            if (!r.deferred) {
                //获取下一个nextReceiver的uid
                final int receiverUid = r.getReceiverUid(r.receivers.get(r.nextReceiver));
                //如果
                if (mDispatcher.isDeferringLocked(receiverUid)) {
                    if (DEBUG_BROADCAST_DEFERRAL) {
                        Slog.i(TAG_BROADCAST, "Next receiver in " + r + " uid " + receiverUid
                                + " at " + r.nextReceiver + " is under deferral");
                    }
                    // If this is the only (remaining) receiver in the broadcast, "splitting"
                    // doesn't make sense -- just defer it as-is and retire it as the
                    // currently active outgoing broadcast.
                    BroadcastRecord defer;
                    // 下一个Receiver将延迟,再下一个Receiver已经没有了
                    if (r.nextReceiver + 1 == numReceivers) {
                        if (DEBUG_BROADCAST_DEFERRAL) {
                            Slog.i(TAG_BROADCAST, "Sole receiver of " + r
                                    + " is under deferral; setting aside and proceeding");
                        }
                        defer = r;
                        // 下一个Receiver将延迟,再下一个Receiver已经没有了,
                        // 则在retireBroadcastLocked中设置mCurrentBroadcast = null(一般在r == mCurrentBroadcast时)
                        mDispatcher.retireBroadcastLocked(r);
                    } else {
                        // Nontrivial case; split out 'uid's receivers to a new broadcast record
                        // and defer that, then loop and pick up continuing delivery of the current
                        // record (now absent those receivers).

                        // The split operation is guaranteed to match at least at 'nextReceiver'
                        defer = r.splitRecipientsLocked(receiverUid, r.nextReceiver);
                        if (DEBUG_BROADCAST_DEFERRAL) {
                            Slog.i(TAG_BROADCAST, "Post split:");
                            Slog.i(TAG_BROADCAST, "Original broadcast receivers:");
                            for (int i = 0; i < r.receivers.size(); i++) {
                                Slog.i(TAG_BROADCAST, "  " + r.receivers.get(i));
                            }
                            Slog.i(TAG_BROADCAST, "Split receivers:");
                            for (int i = 0; i < defer.receivers.size(); i++) {
                                Slog.i(TAG_BROADCAST, "  " + defer.receivers.get(i));
                            }
                        }
                        // Track completion refcount as well if relevant
                        if (r.resultTo != null) {
                            int token = r.splitToken;
                            if (token == 0) {
                                // first split of this record; refcount for 'r' and 'deferred'
                                r.splitToken = defer.splitToken = nextSplitTokenLocked();
                                mSplitRefcounts.put(r.splitToken, 2);
                                if (DEBUG_BROADCAST_DEFERRAL) {
                                    Slog.i(TAG_BROADCAST,
                                            "Broadcast needs split refcount; using new token "
                                                    + r.splitToken);
                                }
                            } else {
                                // new split from an already-refcounted situation; increment count
                                final int curCount = mSplitRefcounts.get(token);
                                if (DEBUG_BROADCAST_DEFERRAL) {
                                    if (curCount == 0) {
                                        Slog.wtf(TAG_BROADCAST,
                                                "Split refcount is zero with token for " + r);
                                    }
                                }
                                mSplitRefcounts.put(token, curCount + 1);
                                if (DEBUG_BROADCAST_DEFERRAL) {
                                    Slog.i(TAG_BROADCAST, "New split count for token " + token
                                            + " is " + (curCount + 1));
                                }
                            }
                        }
                    }
                    //将defer添加到延迟广播中,按照uid放入
                    mDispatcher.addDeferredBroadcast(receiverUid, defer);
                    //r == null会继续while循环
                    r = null;
                    looped = true;
                    continue;
                }
            }
        } while (r == null);

//BroadcastDispatcher.java
    //获取下一个处理的广播BroadcastRecord next,上面mDispatcher.getNextBroadcastLocked调用
	//这里除了mOrderedBroadcasts有序广播队列,还多了mAlarmBroadcasts(alarm设置的)、mDeferredBroadcasts(延迟广播)的概念
    public BroadcastRecord getNextBroadcastLocked(final long now) {
        //如果当前mCurrentBroadcast还在处理,则直接返回mCurrentBroadcast
        if (mCurrentBroadcast != null) {
            return mCurrentBroadcast;
        }

        //是否有oder的广播,如果有,则someQueued = true
        final boolean someQueued = !mOrderedBroadcasts.isEmpty();

        BroadcastRecord next = null;

        //mAlarmBroadcasts不为空的时候
        if (!mAlarmBroadcasts.isEmpty()) {
            // 首先取出的就是mAlarmBroadcasts中的Deferrals d
            // 然后取出BroadcastRecord next = d.broadcasts.remove(0)
            next = popLocked(mAlarmBroadcasts);
            if (DEBUG_BROADCAST_DEFERRAL && next != null) {
                Slog.i(TAG, "Next broadcast from alarm targets: " + next);
            }
        }

        //如果next为null,而且mDeferredBroadcasts还有内容
        if (next == null && !mDeferredBroadcasts.isEmpty()) {
            // We're going to deliver either:
            // 1. the next "overdue" deferral; or
            // 2. the next ordinary ordered broadcast; *or*
            // 3. the next not-yet-overdue deferral.

            for (int i = 0; i < mDeferredBroadcasts.size(); i++) {
                Deferrals d = mDeferredBroadcasts.get(i);

                //查看一下当前now是否小于d.deferUntil(延迟分发时间,默认是延迟5s)
                //而且someQueued为true,就是有order的时候才break?(跳过这个延迟广播)
                if (now < d.deferUntil && someQueued) {
                    // stop looking when we haven't hit the next time-out boundary
                    // but only if we have un-deferred broadcasts waiting,
                    // otherwise we can deliver whatever deferred broadcast
                    // is next available.
                    break;
                }

                if (d.broadcasts.size() > 0) {
                    //取出next
                    next = d.broadcasts.remove(0);
                    // apply deferral-interval decay policy and move this uid's
                    // deferred broadcasts down in the delivery queue accordingly
                    //将这个Deferrals d从mDeferredBroadcasts移除,代表已经处理了
                    mDeferredBroadcasts.remove(i); // already 'd'

                    //deferredBy*0.75在赋值给deferredBy(第一次deferredBy是5s)
                    d.deferredBy = calculateDeferral(d.deferredBy);

                    //延迟时间deferUntil + deferredBy*0.75,再给新的Deferrals d
                    d.deferUntil += d.deferredBy;
                    //重新根据deferUntil排序放入mDeferredBroadcasts

                    //貌似d.broadcasts如果此时为null,不需要再次将d加入mDeferredBroadcasts了吧?
                    insertLocked(mDeferredBroadcasts, d);
                    if (DEBUG_BROADCAST_DEFERRAL) {
                        Slog.i(TAG, "Next broadcast from deferrals " + next
                                + ", deferUntil now " + d.deferUntil);
                    }
                    break;
                }
            }
        }

        //如果next还是null,而且someQueued=true(有oder的广播)
        if (next == null && someQueued) {
            //则取出order的广播
            next = mOrderedBroadcasts.remove(0);
            if (DEBUG_BROADCAST_DEFERRAL) {
                Slog.i(TAG, "Next broadcast from main queue: " + next);
            }
        }

        //当前正在处理的广播
        mCurrentBroadcast = next;
        return next;
    }

4.4.4 处理下一个接收者nextReceiver

  1. 第一个接收者会设置r.dispatchTime广播分发时间(SystemClock.uptimeMillis当前时间,不受系统时间修改影响)、
    r.dispatchClockTime分发的系统时间(System.currentTimeMillis,该时间会随系统时间变化而变化)
  2. 设置超时时间setBroadcastTimeoutLocked(前台是10s超时,后台是60s超时,针对是单个注册者的时间),
    每个有序的接受者,都是从取出开始算时间r.receiverTime = SystemClock.uptimeMillis();
  3. 开始处理时输出如:"Processing ordered broadcast"类似的日志
        // Get the next receiver...
        // 正常取出一个广播r != null
        //先将nextReceiver赋值给recIdx,然后nextReceiver++,下一次进来nextReceiver就不会时当前这个了
        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.
        //设置receiver接受时间receiverTime
        r.receiverTime = SystemClock.uptimeMillis();
        if (recIdx == 0) {
            //如果recIdx是第一个,这将receiverTime设置给dispatchTime(这个广播的分发时间)
            r.dispatchTime = r.receiverTime;
            //设置分发的系统时间(修改系统时间这个时间会变化)
            r.dispatchClockTime = System.currentTimeMillis();

            if (mLogLatencyMetrics) {
                //输出日志到FrameworkStatsLog中
                FrameworkStatsLog.write(
                        FrameworkStatsLog.BROADCAST_DISPATCH_LATENCY_REPORTED,
                        r.dispatchClockTime - r.enqueueClockTime);
            }

            //trace相关
            if (Trace.isTagEnabled(Trace.TRACE_TAG_ACTIVITY_MANAGER)) {
                Trace.asyncTraceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER,
                        createBroadcastTraceTitle(r, BroadcastRecord.DELIVERY_PENDING),
                        System.identityHashCode(r));
                Trace.asyncTraceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER,
                        createBroadcastTraceTitle(r, BroadcastRecord.DELIVERY_DELIVERED),
                        System.identityHashCode(r));
            }
            //输出开始发送order的广播
            if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG_BROADCAST, "Processing ordered broadcast ["
                    + mQueueName + "] " + r);
        }

        //如果还没有设置超时时间,此处设置超时时间
        if (! mPendingBroadcastTimeoutMessage) {
            //单个广播超时时间是10s(前台)或者60s(后台广播)
            long timeoutTime = r.receiverTime + mConstants.TIMEOUT;
            if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST,
                    "Submitting BROADCAST_TIMEOUT_MSG ["
                            + mQueueName + "] for " + r + " at " + timeoutTime);
            setBroadcastTimeoutLocked(timeoutTime);
        }

4.4.5 发送给动态注册的order注册者

  1. 使用的方法是deliverToRegisteredReceiverLocked,和平行广播类似,都是处理动态注册的接受者,
    只是这里是按顺序,一个个处理
  2. 输出日志如:“Delivering ordered [foreground/background] to registered ***”
        final BroadcastOptions brOptions = r.options;

        //获取下一个接受者
        final Object nextReceiver = r.receivers.get(recIdx);

        //如果这个nextReceiver为BroadcastFilter类型(动态注册广播接收者)
        // BroadcastRecord的receivers还有另一种类型ResolveInfo,是从PMS中查询得到的静态注册广播类型
        if (nextReceiver instanceof BroadcastFilter) {
            // Simple case: this is a registered receiver who gets
            // a direct call.
            BroadcastFilter filter = (BroadcastFilter)nextReceiver;
            if (DEBUG_BROADCAST)  Slog.v(TAG_BROADCAST,
                    "Delivering ordered ["
                            + mQueueName + "] to registered "
                            + filter + ": " + r);
            //发送给动态注册的广播
            deliverToRegisteredReceiverLocked(r, filter, r.ordered, recIdx);
            //如果r.receiver == null(没有正在执行的广播)
            //而且该广播是非order的
            if (r.receiver == null || !r.ordered) {
                // The receiver has already finished, so schedule to
                // process the next one.
                if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Quick finishing ["
                        + mQueueName + "]: ordered="
                        + r.ordered + " receiver=" + r.receiver);
                r.state = BroadcastRecord.IDLE;
                //已经发出去执行了,无需等待,直接处理下一个
                scheduleBroadcastsLocked();
            } else {
                if (filter.receiverList != null) {
                    maybeAddAllowBackgroundActivityStartsToken(filter.receiverList.app, r);
                    // r is guaranteed ordered at this point, so we know finishReceiverLocked()
                    // will get a callback and handle the activity start token lifecycle.
                }
            }
            //直接返回,代表本次完成,一次处理一个广播中的nextReceiver
            return;
        }

4.4.6 静态注册者跳过的逻辑

跳过的逻辑较多,
这里注意一下“Background execution not allowed”,如果flag设置了FLAG_RECEIVER_EXCLUDE_BACKGROUND则无法让后台接收,
或者getComponent/getPackage都为null,而且没有设置FLAG_RECEIVER_INCLUDE_BACKGROUND,而且没有requiredPermissions,
则无法发送给后台的进程(进程状态procState>=PROCESS_STATE_TRANSIENT_BACKGROUND(8)属于广播的后台进程)

        // Hard case: need to instantiate the receiver, possibly
        // starting its application process to host it.

        //静态广播的处理
        ResolveInfo info =
                (ResolveInfo)nextReceiver;
        ComponentName component = new ComponentName(
                info.activityInfo.applicationInfo.packageName,
                info.activityInfo.name);

        //注意这里是静态广播接收跳过的逻辑,动态注册跳过的逻辑是在deliverToRegisteredReceiverLocked中
        boolean skip = false;
        //判断是否需要跳过
		//sdk的一些判断
        if (brOptions != null &&
                (info.activityInfo.applicationInfo.targetSdkVersion
                        < brOptions.getMinManifestReceiverApiLevel() ||
                        info.activityInfo.applicationInfo.targetSdkVersion
                                > brOptions.getMaxManifestReceiverApiLevel())) {
            Slog.w(TAG, "Target SDK mismatch: receiver " + info.activityInfo
                    + " targets " + info.activityInfo.applicationInfo.targetSdkVersion
                    + " but delivery restricted to ["
                    + brOptions.getMinManifestReceiverApiLevel() + ", "
                    + brOptions.getMaxManifestReceiverApiLevel()
                    + "] broadcasting " + broadcastDescription(r, component));
            skip = true;
        }
		
		//查看发送者的uid和接受者的uid是否一样,或者是否系统uid,确定一些是否两者有设定关联关系association
		//默认返回是true
        if (!skip && !mService.validateAssociationAllowedLocked(r.callerPackage, r.callingUid,
                component.getPackageName(), info.activityInfo.applicationInfo.uid)) {
            Slog.w(TAG, "Association not allowed: broadcasting "
                    + broadcastDescription(r, component));
            skip = true;
        }
        if (!skip) {
            //看一下意图防火墙mIntentFirewall是否有block该发送行为
            skip = !mService.mIntentFirewall.checkBroadcast(r.intent, r.callingUid,
                    r.callingPid, r.resolvedType, info.activityInfo.applicationInfo.uid);
            if (skip) {
                Slog.w(TAG, "Firewall blocked: broadcasting "
                        + broadcastDescription(r, component));
            }
        }
		
		//权限相关的的检查
        int perm = mService.checkComponentPermission(info.activityInfo.permission,
                r.callingPid, r.callingUid, info.activityInfo.applicationInfo.uid,
                info.activityInfo.exported);
        if (!skip && perm != PackageManager.PERMISSION_GRANTED) {
            if (!info.activityInfo.exported) {
                Slog.w(TAG, "Permission Denial: broadcasting "
                        + broadcastDescription(r, component)
                        + " is not exported from uid " + info.activityInfo.applicationInfo.uid);
            } else {
                Slog.w(TAG, "Permission Denial: broadcasting "
                        + broadcastDescription(r, component)
                        + " requires " + info.activityInfo.permission);
            }
            skip = true;
        } else if (!skip && info.activityInfo.permission != null) {
            final int opCode = AppOpsManager.permissionToOpCode(info.activityInfo.permission);
            if (opCode != AppOpsManager.OP_NONE && mService.getAppOpsManager().noteOpNoThrow(opCode,
                    r.callingUid, r.callerPackage, r.callerFeatureId,
                    "Broadcast delivered to " + info.activityInfo.name)
                    != AppOpsManager.MODE_ALLOWED) {
                Slog.w(TAG, "Appop Denial: broadcasting "
                        + broadcastDescription(r, component)
                        + " requires appop " + AppOpsManager.permissionToOp(
                        info.activityInfo.permission));
                skip = true;
            }
        }

        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) {
                Slog.w(TAG, "Permission Denial: Receiver " + component.flattenToShortString()
                        + " requests FLAG_SINGLE_USER, but app does not hold "
                        + android.Manifest.permission.INTERACT_ACROSS_USERS);
                skip = true;
            }
        }
        if (!skip && info.activityInfo.applicationInfo.isInstantApp()
                && r.callingUid != info.activityInfo.applicationInfo.uid) {
            Slog.w(TAG, "Instant App Denial: receiving "
                    + r.intent
                    + " to " + component.flattenToShortString()
                    + " due to sender " + r.callerPackage
                    + " (uid " + r.callingUid + ")"
                    + " Instant Apps do not support manifest receivers");
            skip = true;
        }
        if (!skip && r.callerInstantApp
                && (info.activityInfo.flags & ActivityInfo.FLAG_VISIBLE_TO_INSTANT_APP) == 0
                && r.callingUid != info.activityInfo.applicationInfo.uid) {
            Slog.w(TAG, "Instant App Denial: receiving "
                    + r.intent
                    + " to " + component.flattenToShortString()
                    + " requires receiver have visibleToInstantApps set"
                    + " due to sender " + r.callerPackage
                    + " (uid " + r.callingUid + ")");
            skip = true;
        }
		
		//crash的app则直接跳过
        if (r.curApp != null && r.curApp.mErrorState.isCrashing()) {
            // If the target process is crashing, just skip it.
            Slog.w(TAG, "Skipping deliver ordered [" + mQueueName + "] " + r
                    + " to " + r.curApp + ": process 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) {
                // all such failures mean we skip this receiver
                Slog.w(TAG, "Exception getting recipient info for "
                        + info.activityInfo.packageName, e);
            }
			//确定是否可用
            if (!isAvailable) {
                Slog.w(TAG_BROADCAST,
                        "Skipping delivery to " + info.activityInfo.packageName + " / "
                                + info.activityInfo.applicationInfo.uid
                                + " : package no longer available");
                skip = true;
            }
        }

        // If permissions need a review before any of the app components can run, we drop
        // the broadcast and if the calling app is in the foreground and the broadcast is
        // explicit we launch the review UI passing it a pending intent to send the skipped
        // broadcast.
        if (!skip) {
            //判断是否需要权限来启动,如果需要则跳过(如果调用者是前台,而且发送到特定组件,则启动权限申请的ui界面)
            if (!requestStartTargetPermissionsReviewIfNeededLocked(r,
                    info.activityInfo.packageName, UserHandle.getUserId(
                            info.activityInfo.applicationInfo.uid))) {
                Slog.w(TAG_BROADCAST,
                        "Skipping delivery: permission review required for "
                                + broadcastDescription(r, component));
                skip = true;
            }
        }

        // This is safe to do even if we are skipping the broadcast, and we need
        // this information now to evaluate whether it is going to be allowed to run.
        //接收者的uid
        final int receiverUid = info.activityInfo.applicationInfo.uid;
        // If it's a singleton, it needs to be the same app or a special app
        if (r.callingUid != Process.SYSTEM_UID && isSingleton
                && mService.isValidSingletonCall(r.callingUid, receiverUid)) {
            info.activityInfo = mService.getActivityInfoForUser(info.activityInfo, 0);
        }
        //接受者的进程名字
        String targetProcess = info.activityInfo.processName;

        //接受者的进程ProcessRecord app,这个可能为null,也就是进程未启动
        ProcessRecord app = mService.getProcessRecordLocked(targetProcess,
                info.activityInfo.applicationInfo.uid);

        if (!skip) {
            final int allowed = mService.getAppStartModeLOSP(
                    info.activityInfo.applicationInfo.uid, info.activityInfo.packageName,
                    info.activityInfo.applicationInfo.targetSdkVersion, -1, true, false, false);

/*
//进程状态,只有小于8才会被认为可以接收广播(不带getComponent、getPackage)
    public static final boolean isProcStateBackground(int procState) {
        return procState >= PROCESS_STATE_TRANSIENT_BACKGROUND;
    }
    //PROCESS_STATE_TRANSIENT_BACKGROUND后台临时的一个状态(一般的含义,如toasts)
    //1.如果设置了getForcingToImportant不为null(调用AMS的setProcessImportant设置),会设置该状态,
    //而且adj是用户可感知的PERCEPTIBLE_APP_ADJ,例如toasts是这种情况(NotificationManagerService中调用setProcessImportant)
    //2.AMS的mBackupTargets是该app,且其adj大于BACKUP_APP_ADJ,会设置该值
    //3.service服务依赖:如果设置了BIND_NOT_FOREGROUND(非前台绑定)而且没有设置BIND_IMPORTANT_BACKGROUND(绑定重要后台)的时候,
    //且客户端状态优先级小于该值时,会设置该值
    TRANSIENT_BACKGROUND = 8,
*/

            if (allowed != ActivityManager.APP_START_MODE_NORMAL) {
                // We won't allow this receiver to be launched if the app has been
                // completely disabled from launches, or it was not explicitly sent
                // to it and the app is in a state that should not receive it
                // (depending on how getAppStartModeLOSP has determined that).
                if (allowed == ActivityManager.APP_START_MODE_DISABLED) {
                    Slog.w(TAG, "Background execution disabled: receiving "
                            + r.intent + " to "
                            + component.flattenToShortString());
                    skip = true;
                    //如果flag设置了FLAG_RECEIVER_EXCLUDE_BACKGROUND则无法让后台接收
                    //或者getComponent/getPackage都为null,而且没有设置FLAG_RECEIVER_INCLUDE_BACKGROUND,而且没有requiredPermissions
                    //如ACTION_BOOT_COMPLETED是有设置FLAG_RECEIVER_INCLUDE_BACKGROUND,所以静态广播无需权限就可以直接接收
                } 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());
                    Slog.w(TAG, "Background execution not allowed: receiving "
                            + r.intent + " to "
                            + component.flattenToShortString());
                    skip = true;
                }
            }
        }

        if (!skip && !Intent.ACTION_SHUTDOWN.equals(r.intent.getAction())
                && !mService.mUserController
                .isUserRunning(UserHandle.getUserId(info.activityInfo.applicationInfo.uid),
                        0 /* flags */)) {
            skip = true;
            Slog.w(TAG,
                    "Skipping delivery to " + info.activityInfo.packageName + " / "
                            + info.activityInfo.applicationInfo.uid + " : user is not running");
        }

		//处理不包含的权限excludedPermissions
        if (!skip && r.excludedPermissions != null && r.excludedPermissions.length > 0) {
            for (int i = 0; i < r.excludedPermissions.length; i++) {
                String excludedPermission = r.excludedPermissions[i];
                try {
                    perm = AppGlobals.getPackageManager()
                            .checkPermission(excludedPermission,
                                    info.activityInfo.applicationInfo.packageName,
                                    UserHandle
                                            .getUserId(info.activityInfo.applicationInfo.uid));
                } catch (RemoteException e) {
                    perm = PackageManager.PERMISSION_DENIED;
                }

                int appOp = AppOpsManager.permissionToOpCode(excludedPermission);
                if (appOp != AppOpsManager.OP_NONE) {
                    // When there is an app op associated with the permission,
                    // skip when both the permission and the app op are
                    // granted.
                    if ((perm == PackageManager.PERMISSION_GRANTED) && (
                            mService.getAppOpsManager().checkOpNoThrow(appOp,
                                    info.activityInfo.applicationInfo.uid,
                                    info.activityInfo.packageName)
                                    == AppOpsManager.MODE_ALLOWED)) {
                        skip = true;
                        break;
                    }
                } else {
                    // When there is no app op associated with the permission,
                    // skip when permission is granted.
                    if (perm == PackageManager.PERMISSION_GRANTED) {
                        skip = true;
                        break;
                    }
                }
            }
        }

		//处理需要包含的权限requiredPermission
        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) {
                    Slog.w(TAG, "Permission Denial: receiving "
                            + r.intent + " to "
                            + component.flattenToShortString()
                            + " requires " + requiredPermission
                            + " due to sender " + r.callerPackage
                            + " (uid " + r.callingUid + ")");
                    skip = true;
                    break;
                }
                int appOp = AppOpsManager.permissionToOpCode(requiredPermission);
                if (appOp != AppOpsManager.OP_NONE && appOp != r.appOp) {
                    if (!noteOpForManifestReceiver(appOp, r, info, component)) {
                        skip = true;
                        break;
                    }
                }
            }
        }
        if (!skip && r.appOp != AppOpsManager.OP_NONE) {
            //AppOps相关判断
            if (!noteOpForManifestReceiver(r.appOp, r, info, component)) {
                skip = true;
            }
        }

        //上面都是各类判断是否需要跳过的逻辑skip
        if (skip) {
            if (DEBUG_BROADCAST)  Slog.v(TAG_BROADCAST,
                    "Skipping delivery of ordered [" + mQueueName + "] "
                            + r + " for reason described above");

            //如果需要跳过,标定当前r.delivery[recIdx]为skipped
            r.delivery[recIdx] = BroadcastRecord.DELIVERY_SKIPPED;
            //跳过的时候清空r.receiver = null
            r.receiver = null;
            r.curFilter = null;
            r.state = BroadcastRecord.IDLE;
            //静态广播跳过++
            r.manifestSkipCount++;
            //继续下一个分发
            scheduleBroadcastsLocked();
            return;
        }

4.4.7 发送给已经启动了的静态注册者

  1. 对于已经启动了的静态注册者,则直接调用processCurBroadcastLocked去发送给静态注册者
  2. 静态接收者都是在APP主线程中分发
  3. APP线程handleReceiver会新建BroadcastReceiver实例,执行onReceive方法,然后调用AMS的finishReceiver方法

ps: 注意一下,此处广播记录的状态设置成app接收“r.state = BroadcastRecord.APP_RECEIVE”,
设置当前接收的组件r.curComponent = component

        //静态广播Count执行++
        r.manifestCount++;

        //标定当前r.delivery[recIdx]为分发DELIVERED
        r.delivery[recIdx] = BroadcastRecord.DELIVERY_DELIVERED;
        //状态修改成app接收APP_RECEIVE,后面该receive finishReceiver返回的时候APP_RECEIVE或BroadcastRecord.CALL_DONE_RECEIVE才会继续处理下一个
        r.state = BroadcastRecord.APP_RECEIVE;
        //当前接收组件curComponent
        r.curComponent = component;
        //当前的receiver
        r.curReceiver = info.activityInfo;
        if (DEBUG_MU && r.callingUid > UserHandle.PER_USER_RANGE) {
            Slog.v(TAG_MU, "Updated broadcast record activity info for secondary user, "
                    + info.activityInfo + ", callingUid = " + r.callingUid + ", uid = "
                    + receiverUid);
        }
        final boolean isActivityCapable =
                (brOptions != null && brOptions.getTemporaryAppAllowlistDuration() > 0);
        maybeScheduleTempAllowlistLocked(receiverUid, r, brOptions);

        // Report that a component is used for explicit broadcasts.
        if (r.intent.getComponent() != null && r.curComponent != null
                && !TextUtils.equals(r.curComponent.getPackageName(), r.callerPackage)) {
            mService.mUsageStatsService.reportEvent(
                    r.curComponent.getPackageName(), r.userId, Event.APP_COMPONENT_USED);
        }

        // Broadcast is being executed, its package can't be stopped.
        try {
            //设置包的stop状态是false(需要启动改应用了,包不再是stop了)
            AppGlobals.getPackageManager().setPackageStoppedState(
                    r.curComponent.getPackageName(), false, r.userId);
        } catch (RemoteException e) {
        } catch (IllegalArgumentException e) {
            Slog.w(TAG, "Failed trying to unstop package "
                    + r.curComponent.getPackageName() + ": " + e);
        }

        // Is this receiver's application already running?
        //如果app之前已经启动
        if (app != null && app.getThread() != null && !app.isKilled()) {
            try {
                app.addPackage(info.activityInfo.packageName,
                        info.activityInfo.applicationInfo.longVersionCode, mService.mProcessStats);
                maybeAddAllowBackgroundActivityStartsToken(app, r);
                //则直接发送该广播到app中
                processCurBroadcastLocked(r, app);
                return;
            } catch (RemoteException e) {
                Slog.w(TAG, "Exception when sending broadcast to "
                        + r.curComponent, e);
            } catch (RuntimeException e) {
                Slog.wtf(TAG, "Failed sending broadcast to "
                        + r.curComponent + " with " + r.intent, e);
                // If some unexpected exception happened, just skip
                // this broadcast.  At this point we are not in the call
                // from a client, so throwing an exception out from here
                // will crash the entire system instead of just whoever
                // sent the broadcast.
                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;
            }

            // If a dead object exception was thrown -- fall through to
            // restart the application.
        }

//发送给静态注册者的函数processCurBroadcastLocked
    private final void processCurBroadcastLocked(BroadcastRecord r,
                                                 ProcessRecord app) throws RemoteException {
        if (DEBUG_BROADCAST)  Slog.v(TAG_BROADCAST,
                "Process cur broadcast " + r + " for app " + app);
        final IApplicationThread thread = app.getThread();
        if (thread == null) {
            throw new RemoteException();
        }
        if (app.isInFullBackup()) {
            skipReceiverLocked(r);
            return;
        }

        //processCurBroadcastLocked的时候,会有r.receiver的设置
        r.receiver = thread.asBinder();
        r.curApp = app;
        final ProcessReceiverRecord prr = app.mReceivers;
        prr.addCurReceiver(r);
        app.mState.forceProcessStateUpTo(ActivityManager.PROCESS_STATE_RECEIVER);
        mService.updateLruProcessLocked(app, false, null);
        // Make sure the oom adj score is updated before delivering the broadcast.
        // Force an update, even if there are other pending requests, overall it still saves time,
        // because time(updateOomAdj(N apps)) <= N * time(updateOomAdj(1 app)).
        mService.enqueueOomAdjTargetLocked(app);
        mService.updateOomAdjPendingTargetsLocked(OomAdjuster.OOM_ADJ_REASON_START_RECEIVER);

        // Tell the application to launch this receiver.
		//r.curComponent是发送给静态接收者的时候设置的组件名字
        r.intent.setComponent(r.curComponent);

        boolean started = false;
        try {
            if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG_BROADCAST,
                    "Delivering to component " + r.curComponent
                            + ": " + r);
            mService.notifyPackageUse(r.intent.getComponent().getPackageName(),
                    PackageManager.NOTIFY_PACKAGE_USE_BROADCAST_RECEIVER);
            //发送给app主线程的scheduleReceiver
            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());
            if (DEBUG_BROADCAST)  Slog.v(TAG_BROADCAST,
                    "Process cur broadcast " + r + " DELIVERED for app " + app);
            started = true;
        } finally {
            if (!started) {
                if (DEBUG_BROADCAST)  Slog.v(TAG_BROADCAST,
                        "Process cur broadcast " + r + ": NOT STARTED!");
                //没有启动成功,还原状态
                r.receiver = null;
                r.curApp = null;
                prr.removeCurReceiver(r);
            }
        }
    }

//ActivityThread.java
        //APP的接受者,在主线程中运行
        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);
        }

        public void handleMessage(Message msg) {
            if (DEBUG_MESSAGES) Slog.v(TAG, ">>> handling: " + codeToString(msg.what));
            switch (msg.what) {
			//...
                case RECEIVER:
                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "broadcastReceiveComp");
					//处理广播接收者
                    handleReceiver((ReceiverData)msg.obj);
                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
                    break;
			//...
        }

    private void handleReceiver(ReceiverData data) {
        // If we are getting ready to gc after going to the background, well
        // we are back active so skip it.
        unscheduleGcIdler();

		//获取相关组件
        String component = data.intent.getComponent().getClassName();

        LoadedApk packageInfo = getPackageInfoNoCheck(
                data.info.applicationInfo, data.compatInfo);

        IActivityManager mgr = ActivityManager.getService();

        Application app;
        BroadcastReceiver receiver;
        ContextImpl context;
		//新建一个静态接收者的实例BroadcastReceiver
        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);
			//通过class loader,新建一个接收者的实例,(BroadcastReceiver) cl.loadClass(className).newInstance()
			//如实例化MyReceiver
            receiver = packageInfo.getAppFactory()
                    .instantiateReceiver(cl, data.info.name, data.intent);
        } catch (Exception e) {
            if (DEBUG_BROADCAST) Slog.i(TAG,
                    "Finishing failed broadcast to " + data.intent.getComponent());
            data.sendFinished(mgr);
            throw new RuntimeException(
                "Unable to instantiate receiver " + component
                + ": " + e.toString(), e);
        }

        try {
            if (localLOGV) Slog.v(
                TAG, "Performing receive of " + data.intent
                + ": app=" + app
                + ", appName=" + app.getPackageName()
                + ", pkg=" + packageInfo.getPackageName()
                + ", comp=" + data.intent.getComponent().toShortString()
                + ", dir=" + packageInfo.getAppDir());

            sCurrentBroadcastIntent.set(data.intent);
            receiver.setPendingResult(data);
			//执行app定义的onReceive方法,如执行MyReceiver的onReceive方法
            receiver.onReceive(context.getReceiverRestrictedContext(),
                    data.intent);
        } catch (Exception e) {
            if (DEBUG_BROADCAST) Slog.i(TAG,
                    "Finishing failed broadcast to " + data.intent.getComponent());
            data.sendFinished(mgr);
            if (!mInstrumentation.onException(receiver, e)) {
                throw new RuntimeException(
                    "Unable to start receiver " + component
                    + ": " + e.toString(), e);
            }
        } finally {
            sCurrentBroadcastIntent.set(null);
        }

        if (receiver.getPendingResult() != null) {
            //BroadcastReceiver.PendingResul(ReceiverData继承PendingResul)的finish
			//具体过程和“4.4.1 mParallelBroadcasts平行广播的分发”是类似的
            data.finish();
        }
    }

4.4.8 启动静态注册接收者的进程

  1. 如果静态注册的接受者进程没有启动,则需要启动,并且挂起该广播mPendingBroadcast分发
        // Not running -- get it started, to be executed when the app comes up.
        //否则第一步,我们需要先启动该进程
        if (DEBUG_BROADCAST)  Slog.v(TAG_BROADCAST,
                "Need to start app ["
                        + mQueueName + "] " + targetProcess + " for broadcast " + r);
        //启动进程ZYGOTE_POLICY_FLAG_LATENCY_SENSITIVE(延迟敏感的)标签用于确定fork进程时是否需要使用usap
        r.curApp = mService.startProcessLocked(targetProcess,
                info.activityInfo.applicationInfo, true,
                r.intent.getFlags() | Intent.FLAG_FROM_BACKGROUND,
                new HostingRecord("broadcast", r.curComponent), isActivityCapable
                        ? ZYGOTE_POLICY_FLAG_LATENCY_SENSITIVE : ZYGOTE_POLICY_FLAG_EMPTY,
                (r.intent.getFlags() & Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0, false);
        if (r.curApp == null) {
            // Ah, this recipient is unavailable.  Finish it if necessary,
            // and mark the broadcast record as ready for the next.
            //当无法启动app的时候,完成这个广播BroadcastRecord r的分发finishReceiverLocked
            Slog.w(TAG, "Unable to launch app "
                    + info.activityInfo.applicationInfo.packageName + "/"
                    + receiverUid + " for broadcast "
                    + r.intent + ": process is bad");
            logBroadcastReceiverDiscardLocked(r);
            finishReceiverLocked(r, r.resultCode, r.resultData,
                    r.resultExtras, r.resultAbort, false);
            scheduleBroadcastsLocked();
            r.state = BroadcastRecord.IDLE;
            return;
        }

        maybeAddAllowBackgroundActivityStartsToken(r.curApp, r);

        // Need to start app 需要先启动该进程会设置mPendingBroadcast = r;
        //启动进程后会调用attachApplicationLocked(AMS)、bindApplication(IApplicationThread)
        //attachApplicationLocked(AMS)-> sendPendingBroadcastsLocked 会处理mPendingBroadcast
        mPendingBroadcast = r;
        //mPendingBroadcastRecvIndex是当前需要处理recevie的recIdx
        mPendingBroadcastRecvIndex = recIdx;
    }
  1. 从APP进程启动到回传AMS

=> mService.startProcessLocked启动进程后,
会调用ActivityThread的main方法:创建main loop,调用thread.attach,Looper.loop开始消息队列的循环

//ActivityThread.java
    public static void main(String[] args) {
        Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "ActivityThreadMain");

        // Install selective syscall interception
        AndroidOs.install();

        // CloseGuard defaults to true and can be quite spammy.  We
        // disable it here, but selectively enable it later (via
        // StrictMode) on debug builds, but using DropBox, not logs.
        CloseGuard.setEnabled(false);

        Environment.initForCurrentUser();

        // Make sure TrustedCertificateStore looks in the right place for CA certificates
        final File configDir = Environment.getUserConfigDirectory(UserHandle.myUserId());
        TrustedCertificateStore.setDefaultUserDirectory(configDir);

        // Call per-process mainline module initialization.
		//google main line的模块初始化
        initializeMainlineModules();

		//设置该进程刚刚创建,名字是"<pre-initialized>"
		//在handleBindApplication之后app才会设置成对应的进程名字processName
        Process.setArgV0("<pre-initialized>");

		//准备主线程,此处H mH = new H();才能从Looper.myLooper()获取主线程的sMainLooper
        Looper.prepareMainLooper();

        // Find the value for {@link #PROC_START_SEQ_IDENT} if provided on the command line.
        // It will be in the format "seq=114"
        long startSeq = 0;
        if (args != null) {
            for (int i = args.length - 1; i >= 0; --i) {
                if (args[i] != null && args[i].startsWith(PROC_START_SEQ_IDENT)) {
                    startSeq = Long.parseLong(
                            args[i].substring(PROC_START_SEQ_IDENT.length()));
                }
            }
        }
		
		//这里是接下去的流程
        ActivityThread thread = new ActivityThread();
        thread.attach(false, startSeq);

        if (sMainThreadHandler == null) {
            sMainThreadHandler = thread.getHandler();
        }

        if (false) {
            Looper.myLooper().setMessageLogging(new
                    LogPrinter(Log.DEBUG, "ActivityThread"));
        }

        // End of event ActivityThreadMain.
        Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
		//开始loop的循环,此时ActivityThread主线程mH的消息队列才开始分发
        Looper.loop();

        throw new RuntimeException("Main thread loop unexpectedly exited");
    }

	//附着方法attach
    private void attach(boolean system, long startSeq) {
        sCurrentActivityThread = this;
        mConfigurationController = new ConfigurationController(this);
        mSystemThread = system;
        if (!system) {
            //app进程的逻辑
            android.ddm.DdmHandleAppName.setAppName("<pre-initialized>",
                                                    UserHandle.myUserId());
            RuntimeInit.setApplicationObject(mAppThread.asBinder());
            final IActivityManager mgr = ActivityManager.getService();
            try {
                //调用的是AMS的attachApplication
                mgr.attachApplication(mAppThread, startSeq);
            //...
        } else {
            // Don't set application object here -- if the system crashes,
            // we can't display an alert, we just want to die die die.
			//系统进程的逻辑
            android.ddm.DdmHandleAppName.setAppName("system_process",
                    UserHandle.myUserId());
            try {
                mInstrumentation = new Instrumentation();
                mInstrumentation.basicInit(this);
                ContextImpl context = ContextImpl.createAppContext(
                        this, getSystemContext().mPackageInfo);
                mInitialApplication = context.mPackageInfo.makeApplication(true, null);
                mInitialApplication.onCreate();
            } catch (Exception e) {
                throw new RuntimeException(
                        "Unable to instantiate Application():" + e.toString(), e);
            }
        }

        //...
    }
  1. AMS开始处理挂起的广播

=> AMS收到app的attachApplication,查看是否有挂起的广播isPendingBroadcastProcessLocked,
如果有则让广播队列处理该app挂起的广播sendPendingBroadcastsLocked

//ActivityManagerService.java
    //从app调用的attachApplication(附着在应用)方法
    public final void attachApplication(IApplicationThread thread, long startSeq) {
        if (thread == null) {
            throw new SecurityException("Invalid application interface");
        }
        synchronized (this) {
            int callingPid = Binder.getCallingPid();
            final int callingUid = Binder.getCallingUid();
            final long origId = Binder.clearCallingIdentity();
			//attachApplicationLocked,加个Locked,这类方法代表需要上锁才能调用
            attachApplicationLocked(thread, callingPid, callingUid, startSeq);
            Binder.restoreCallingIdentity(origId);
        }
    }

    private boolean attachApplicationLocked(@NonNull IApplicationThread thread,
            int pid, int callingUid, long startSeq) {
        //...
		//绑定pid到ProcessRecord,用于死亡回调AppDeathRecipient
        if (DEBUG_ALL) Slog.v(
                TAG, "Binding process pid " + pid + " to record " + app);

        final String processName = app.processName;
        try {
            AppDeathRecipient adr = new AppDeathRecipient(
                    app, pid, thread);
            thread.asBinder().linkToDeath(adr, 0);
            app.setDeathRecipient(adr);
        } catch (RemoteException e) {
            app.resetPackageList(mProcessStats);
            mProcessList.startProcessLocked(app,
                    new HostingRecord("link fail", processName),
                    ZYGOTE_POLICY_FLAG_EMPTY);
            return false;
        }

		//这个就是event log中经常出现的"am_proc_bound",代表进程创建后,app进程回调AMS绑定了该app进程
        EventLogTags.writeAmProcBound(app.userId, pid, app.processName);

		//进程信息记录ProcessRecord app的初始化
        
            //...
			//同时这里还会从system_server回传APP进程,去绑定应用bindApplication
                thread.bindApplication(processName, appInfo, providerList, null, profilerInfo,
                        null, null, null, testMode,
                        mBinderTransactionTrackingEnabled, enableTrackAllocation,
                        isRestrictedBackupMode || !normalMode, app.isPersistent(),
                        new Configuration(app.getWindowProcessController().getConfiguration()),
                        app.getCompat(), getCommonServicesLocked(app.isolated),
                        mCoreSettingsObserver.getCoreSettingsLocked(),
                        buildSerial, autofillOptions, contentCaptureOptions,
                        app.getDisabledCompatChanges(), serializedSystemFontMap);
            //...

        // 调用ActivityTaskManagerService的attachApplication(activity是否需要运行)
        if (normalMode) {
            try {
                didSomething = mAtmInternal.attachApplication(app.getWindowProcessController());
            } catch (Exception e) {
                Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
                badApp = true;
            }
        }

        // 调用ActiveServices的attachApplication(services是否需要运行)
        if (!badApp) {
            try {
                didSomething |= mServices.attachApplicationLocked(app, processName);
                checkTime(startTime, "attachApplicationLocked: after mServices.attachApplicationLocked");
            } catch (Exception e) {
                Slog.wtf(TAG, "Exception thrown starting services in " + app, e);
                badApp = true;
            }
        }

        // 看一下是否有挂起的广播需要运行
        if (!badApp && isPendingBroadcastProcessLocked(pid)) {
            try {
                //向广播队列告知,有挂起的进程启动
                didSomething |= sendPendingBroadcastsLocked(app);
                checkTime(startTime, "attachApplicationLocked: after sendPendingBroadcastsLocked");
            } catch (Exception e) {
                // If the app died trying to launch the receiver we declare it 'bad'
                Slog.wtf(TAG, "Exception thrown dispatching broadcasts in " + app, e);
                badApp = true;
            }
        }

        //...
        return true;
    }

//BroadcastQueue.java
    //遍历所有的广播队列,看一下是否有挂起的广播
    boolean isPendingBroadcastProcessLocked(int pid) {
        return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
                || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
                || mOffloadBroadcastQueue.isPendingBroadcastProcessLocked(pid);
    }

    //查看该pid是否有挂起的广播
    public boolean isPendingBroadcastProcessLocked(int pid) {
        return mPendingBroadcast != null && mPendingBroadcast.curApp.getPid() == pid;
    }
	
	//向广播队列告知,有挂起的进程启动
    // The app just attached; send any pending broadcasts that it should receive
    boolean sendPendingBroadcastsLocked(ProcessRecord app) {
        boolean didSomething = false;
        for (BroadcastQueue queue : mBroadcastQueues) {
            didSomething |= queue.sendPendingBroadcastsLocked(app);
        }
        return didSomething;
    }
  1. 广播队列处理挂起的进程

=> 广播队列处理挂起的进程sendPendingBroadcastsLocked -> processCurBroadcastLocked,
并清除mPendingBroadcast = null,广播分发可以继续下去
=> processCurBroadcastLocked将广播发送给该app的curComponent
=> processCurBroadcastLocked(系统进程BroadcastQueue.java)将该广播传递给curApp-> scheduleReceiver(app进程ActivityThread)
-> RECEIVER -> handleReceiver(ActivityThread.java) -> finish(BroadcastReceiver.java) -> finish/sendFinished(BroadcastReceiver.java)
-> am.finishReceiver(再次回到系统进程AMS)

//BroadcastQueue.java
   // attachApplicationLocked(AMS) -> sendPendingBroadcastsLocked(AMS/BroadcastQueue)
    // 进程启动的时候会清除 mPendingBroadcast
    public boolean sendPendingBroadcastsLocked(ProcessRecord app) {
        boolean didSomething = false;
        final BroadcastRecord br = mPendingBroadcast;
        if (br != null && br.curApp.getPid() > 0 && br.curApp.getPid() == app.getPid()) {
            if (br.curApp != app) {
                Slog.e(TAG, "App mismatch when sending pending broadcast to "
                        + app.processName + ", intended target is " + br.curApp.processName);
                return false;
            }
            try {
                //发送给pending的广播时候会清除 mPendingBroadcast = nul
                mPendingBroadcast = null;
				//"章节4.4.7"中已经讲过这个函数,就是发送给该app的curComponent(静态接收者组件名字)
                processCurBroadcastLocked(br, app);
                didSomething = true;
            } catch (Exception e) {
                Slog.w(TAG, "Exception in new application when starting receiver "
                        + br.curComponent.flattenToShortString(), e);
                logBroadcastReceiverDiscardLocked(br);
                finishReceiverLocked(br, br.resultCode, br.resultData,
                        br.resultExtras, br.resultAbort, false);
                scheduleBroadcastsLocked();
                // We need to reset the state if we failed to start the receiver.
                br.state = BroadcastRecord.IDLE;
                throw new RuntimeException(e.getMessage());
            }
        }
        return didSomething;
    }

4.5 广播接收者处理完成

我们接着讲AMS的finishReceiver,这个是广播接受者接收完成后,回传AMS的方法

4.5.1 广播完成,开始下一个广播的调度

  1. 该广播接收者已经完成了BroadcastRecord.finishReceiverLocked
  2. 开始下一个广播接受者的调度(这里就是order的按顺序的核心)processNextBroadcastLocked(调用这个函数,相当于下一个重复的逻辑,直到全部广播发送完成)
//ActivityManagerService.java
    public void finishReceiver(IBinder who, int resultCode, String resultData,
                               Bundle resultExtras, boolean resultAbort, int flags) {
		//打印该广播接受者完成处理的日志
        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Finish receiver: " + who);

        //...
        final long origId = Binder.clearCallingIdentity();
        try {
            boolean doNext = false;
            BroadcastRecord r;
            BroadcastQueue queue;

            synchronized(this) {
                //查看广播队列属于前台还是后台
                if (isOnOffloadQueue(flags)) {
                    queue = mOffloadBroadcastQueue;
                } else {
                    queue = (flags & Intent.FLAG_RECEIVER_FOREGROUND) != 0
                            ? mFgBroadcastQueue : mBgBroadcastQueue;
                }

				//看一下对应的BroadcastRecord是谁
                r = queue.getMatchingOrderedReceiver(who);
                if (r != null) {
                    //如果BroadcastRecord r存在,则告知广播队列BroadcastQueue,该广播接收者已经完成了finishReceiverLocked
                    doNext = r.queue.finishReceiverLocked(r, resultCode,
                            resultData, resultExtras, resultAbort, true);
                }
				
				//如果doNext正常返回true(上一个正常处理完成返回的就是true)
                if (doNext) {
                    //开始下一个广播接受者的调度,这里就是order的按顺序的核心
                    r.queue.processNextBroadcastLocked(/*fromMsg=*/ false, /*skipOomAdj=*/ true);
                }
                // updateOomAdjLocked() will be done here
                trimApplicationsLocked(false, OomAdjuster.OOM_ADJ_REASON_FINISH_RECEIVER);
            }

        } finally {
            Binder.restoreCallingIdentity(origId);
        }
    }

4.5.2 广播完成finishReceiverLocked

finishReceiverLocked是广播完成时调用,到这里广播的流程基本上就讲完了

//BroadcastQueue.java
    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;
		//app状态变成IDLE
        r.state = BroadcastRecord.IDLE;
		//如果是执行静态注册广播接收的逻辑,这里一般情况是BroadcastRecord.APP_RECEIVE(无超时/无异常情况时)
        if (state == BroadcastRecord.IDLE) {
            Slog.w(TAG_BROADCAST, "finishReceiver [" + mQueueName + "] called but state is IDLE");
        }
        if (r.allowBackgroundActivityStarts && r.curApp != null) {
            if (elapsed > mConstants.ALLOW_BG_ACTIVITY_START_TIMEOUT) {
                // if the receiver has run for more than allowed bg activity start timeout,
                // just remove the token for this process now and we're done
                r.curApp.removeAllowBackgroundActivityStartsToken(r);
            } else {
                // It gets more time; post the removal to happen at the appropriate moment
                postActivityStartTokenRemoval(r.curApp, r);
            }
        }
        // If we're abandoning this broadcast before any receivers were actually spun up,
        // nextReceiver is zero; in which case time-to-process bookkeeping doesn't apply.
        if (r.nextReceiver > 0) {
            r.duration[r.nextReceiver - 1] = elapsed;
        }

        // if this receiver was slow, impose deferral policy on the app.  This will kick in
        // when processNextBroadcastLocked() next finds this uid as a receiver identity.
		//timeoutExempt只有ACTION_PRE_BOOT_COMPLETED才会设置为true,也就是一般会进来
        if (!r.timeoutExempt) {
            // r.curApp can be null if finish has raced with process death - benign
            // edge case, and we just ignore it because we're already cleaning up
            // as expected.
            if (r.curApp != null
                    && mConstants.SLOW_TIME > 0 && elapsed > mConstants.SLOW_TIME) {
                // Core system packages are exempt from deferral policy
				//看一下是否需要加入延迟广播里面
                if (!UserHandle.isCore(r.curApp.uid)) {
                    if (DEBUG_BROADCAST_DEFERRAL) {
                        Slog.i(TAG_BROADCAST, "Broadcast receiver " + (r.nextReceiver - 1)
                                + " was slow: " + receiver + " br=" + r);
                    }
                    mDispatcher.startDeferring(r.curApp.uid);
                } else {
                    if (DEBUG_BROADCAST_DEFERRAL) {
                        Slog.i(TAG_BROADCAST, "Core uid " + r.curApp.uid
                                + " receiver was slow but not deferring: "
                                + receiver + " br=" + r);
                    }
                }
            }
        } else {
            if (DEBUG_BROADCAST_DEFERRAL) {
                Slog.i(TAG_BROADCAST, "Finished broadcast " + r.intent.getAction()
                        + " is exempt from deferral policy");
            }
        }

        //结束的时候r.receiver = null
        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 = nul
        mPendingBroadcast = null;

        r.resultCode = resultCode;
        r.resultData = resultData;
        r.resultExtras = resultExtras;

        // bortBroadcast(应用进程) -> finishReceiver(AMS)-> r.queue.finishReceiverLocked(BroadcastQueue)
        // 只要这个广播没有设置不能中断,则order的广播,优先级在前面的可以中断后续的广播接收
        if (resultAbort && (r.intent.getFlags()&Intent.FLAG_RECEIVER_NO_ABORT) == 0) {
            r.resultAbort = resultAbort;
        } else {
            r.resultAbort = false;
        }

        // If we want to wait behind services *AND* we're finishing the head/
        // active broadcast on its queue
        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;
            }
            // Don't do this if the next receive is in the same process as the current one.
            if (receiver == null || nextReceiver == null
                    || receiver.applicationInfo.uid != nextReceiver.applicationInfo.uid
                    || !receiver.processName.equals(nextReceiver.processName)) {
                // In this case, we are ready to process the next receiver for the current broadcast,
                //?but are on a queue that would like to wait for services to finish before moving
                // on.  If there are background services currently starting, then we will go into a
                // special state where we hold off on continuing this broadcast until they are done.
                //如果该uid的进程有正在启动的后台服务mStartingBackground,则等待后台服务启动完成再继续
                if (mService.mServices.hasBackgroundServicesLocked(r.userId)) {
                    Slog.i(TAG, "Delay finish: " + r.curComponent.flattenToShortString());
                    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.
		//发送给静态注册者的时候一般是APP_RECEIVE,发送给动态注册者的时候一般是CALL_DONE_RECEIVE
        return state == BroadcastRecord.APP_RECEIVE
                || state == BroadcastRecord.CALL_DONE_RECEIVE;
    }

5. 广播的拓展使用

从上面的文章基本上可以知道广播是干什么的,广播的流程是怎么样的。
一般广播的应用有3类:
1、针对高配置的设备:VIP广播,给一些关键的进程,关键的广播,放入特定的队列,不会由于本身广播队列阻塞了其广播分发,
达到比较高效的分发
2、针对低配置的设备:
=> 延迟广播,间隔分发广播等。主要是广播如平行广播一次性发给所有进程,会导致系统负担;
或者是发送给静态注册者需要启动应用,启动多个应用的时候会导致系统负载过重,可以将类似广播延迟分发。
(这个总负载还是一样的,只是分散开来,降低持续卡顿情况,至于偶发的峰值卡顿还是存在,需要别的方法配合)
场景如开机、切换语言等
=> 限制广播:如在特定场景限制启动,限制接收等行为,降低系统负载。
(这类方法效果立竿见影,不过场景需要非常慎重,不然导致功能使用可能出现异常)
=> 其它应用:特定场景修改超时时间,让用户感知的anr减少;针对用户不可见的anr,看一下是否需要用户感知等;接受者优先级调整等。
3、各类广播无法接收问题的解决等(可以考虑动态打开一些基本的调试广播开关DEBUG_BROADCAST DEBUG_BROADCAST_BACKGROUND DEBUG_BROADCAST_DEFERRAL DEBUG_BROADCAST_LIGHT DEBUG_BACKGROUND_CHECK)

了解广播的流程,实现上述内容一般都大概心里有底,会比较快速的做出相应的方案。

### STM32F407 HAL ADC DMA Example Code and Documentation For the STM32F407, using the Hardware Abstraction Layer (HAL) library to configure Analog-to-Digital Converter (ADC) with Direct Memory Access (DMA) involves several key steps. The configuration ensures efficient data acquisition without overburdening the CPU by offloading transfer tasks to hardware. #### Configuration Overview The setup process includes initializing both the ADC peripheral and configuring a DMA channel specifically dedicated to transferring conversion results from the ADC's data register directly into an array in memory[^1]. This method significantly reduces software overhead associated with reading each sample individually via polling or interrupts. #### Initialization Steps To begin, it is necessary to enable clocks for peripherals involved—namely, those related to GPIOs connected as analog inputs along with the ADC itself—and then proceed with setting up parameters such as resolution, alignment within registers, sampling time per channel, etc.. Next comes defining which channels should be included under regular conversions alongside their sequence order; here one can also specify whether continuous mode shall apply so that multiple samples are taken automatically until stopped explicitly through software commands[^4]. Finally, linking everything together requires establishing connections between source (the ADC DR address) and destination addresses where collected values will reside after being transferred across the bus system managed by selected DMA stream/requests pairs. Below demonstrates how these configurations translate into actual C code when employing CubeMX-generated initialization routines supplemented by user-defined functions: ```c // Include headers required for accessing device-specific features. #include "stm32f4xx_hal.h" // Define global variables used throughout program execution flow. extern ADC_HandleTypeDef hadc1; uint16_t adcValues[NUMBER_OF_CHANNELS]; // Buffer holding converted readings. void Start_ADC_DMA(void){ /* Ensure all previous transfers have completed before starting new ones */ __HAL_DMA_DISABLE(&hdma_adc1); /* Clear any pending flags indicating completion status */ __HAL_DMA_CLEAR_FLAG(&hdma_adc1,DMA_FLAG_TCIF0_0|DMA_FLAG_HTIF0_0); /* Begin converting on Regular Channel Group while simultaneously initiating DMA Transfer Request*/ if(HAL_OK != HAL_ADC_Start_DMA(&hadc1,(uint32_t*)adcValues,sizeof(adcValues)/sizeof(uint32_t))){ Error_Handler(); } } ``` This snippet shows essential parts needed to initiate synchronous operation between ADC measurements and automatic storage of outcomes inside `adcValues[]` buffer via direct access provided by configured DMA controller instance (`hdma_adc1`). Note that error handling has been simplified but would typically involve more robust mechanisms depending upon application requirements. --related questions-- 1. How does changing ADC settings affect performance during high-frequency signal acquisitions? 2. What considerations must be made regarding power consumption when implementing ADC with DMA on low-power applications? 3. Can you provide examples demonstrating different modes available for ADC operations like single-shot versus continuous scanning? 4. Is there support for multi-channel simultaneous sampling using this approach? If yes, what modifications might need applying? 5. Are there specific guidelines recommended concerning interrupt priorities assigned to manage potential conflicts among various peripherals sharing resources?
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值