android之基础学习攻克

广播相关学习-sendBroadcast

2018-12-19  本文已影响0人  weiinter105

前言

前面已经介绍过动态注册广播接收者的逻辑,静态注册广播接收者的注册写在manifest中,就不介绍了,下面介绍下发送广播的流程

广播分为以下几类:
1.普通广播

普通广播由发送方调用sendBroadcast及相关重载函数发送。

AMS转发这种类型的广播时,根据BroadcastReceiver的注册方式,进行不同的处理流程。

对于动态注册的广播,理论上可以认为,AMS将在同一时刻,向所有监听此广播的BroadcastReceiver发送消息,因此整体的消息传递的效率比较高。

对于静态注册的广播,AMS将按照有序广播的方式,向BroadcastReceiver发送消息。(因为有可能此时静态注册广播接收者还没起来呢,BroadcastReceiver对象还没创建,也没法向其发送广播,如果同时向静态注册的BroadcastReceiver发送广播,那么可能需要在一段时间内同时创建出大量的进程, 这将对系统造成极大的负担;若以有序广播的方式来发送,那么系统可以依次创建进程, 同时,每次收到上一个广播处理完毕的消息后,都可以尝试清理掉无用的进程。 这样即可以避免突发创建大量的进程,又可以及时回收一些系统资源)

2.有序广播

有序广播由发送方调用sendOrderedBroadcast及相关重载函数发送,是一种串行的广播发送方式。

处理这种类型的广播时,AMS会按照优先级,将广播依次分发给BroadcastReceiver。

AMS收到上一个BroadcastReceiver处理完毕的消息或者超时后,才会将广播发送给下一个BroadcastReceiver。

其中,任意一个BroadcastReceiver,都可以中止后续的广播分发流程。

同时,上一个BroadcastReceiver可以将额外的信息添加到广播中。

3.粘性广播

2321     * @deprecated Sticky broadcasts should not be used.  They provide no security (anyone
2322     * can access them), no protection (anyone can modify them), and many other problems.
2323     * The recommended pattern is to use a non-sticky broadcast to report that <em>something</em>
2324     * has changed, with another mechanism for apps to retrieve the current value whenever
2325     * desired.
2334    @Deprecated
2335    @RequiresPermission(android.Manifest.permission.BROADCAST_STICKY)
2336    public abstract void sendStickyBroadcast(@RequiresPermission Intent intent);

google已不再建议使用粘性广播

Android设计这种广播的初衷是:

正常情况下,假设发送方发送了一个普通广播A。 在广播A发送完毕后,系统中新注册了一个BroadcastReceiver,此时这个BroadcastReceiver是无法收到广播A的。

但是,如果发送方发送的是一个粘性广播B,那么系统将负责存储该粘性广播。 于是,即使BroadcastReceiver在广播B发送完后才注册到系统,这个BroadcastReceiver也会立即收到AMS转发的广播B。

粘性广播和有序广播等概念实际上不是冲突的。 粘性仅仅强调系统将会保存这个广播,它的其它处理过程与上文一致

sendBroadcast流程分析

ContextImpl#sendBroadcast

1013    @Override
1014    public void sendBroadcast(Intent intent) {
1015        warnIfCallingFromSystemProcess();
1016        String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
1017        try {
1018            intent.prepareToLeaveProcess(this);
1019            ActivityManager.getService().broadcastIntent(
1020                    mMainThread.getApplicationThread(), intent, resolvedType, null,
1021                    Activity.RESULT_OK, null, null, null, AppOpsManager.OP_NONE, null, false, false,
1022                    getUserId());
1023        } catch (RemoteException e) {
1024            throw e.rethrowFromSystemServer();
1025        }
1026    }

binder call到AMS,system_server中的binder线程响应broadcastIntent

ActivityManangerService#broadcastIntent

22478    public final int broadcastIntent(IApplicationThread caller,
22479            Intent intent, String resolvedType, IIntentReceiver resultTo,
22480            int resultCode, String resultData, Bundle resultExtras,
22481            String[] requiredPermissions, int appOp, Bundle bOptions,
22482            boolean serialized, boolean sticky, int userId) {
22483        enforceNotIsolatedCaller("broadcastIntent");
22484        synchronized(this) {
22485            intent = verifyBroadcastLocked(intent);
22486
22487            final ProcessRecord callerApp = getRecordForAppLocked(caller);
22488            final int callingPid = Binder.getCallingPid();
22489            final int callingUid = Binder.getCallingUid();
22490            final long origId = Binder.clearCallingIdentity(); //broadcast发送方
22491            int res = broadcastIntentLocked(callerApp,
22492                    callerApp != null ? callerApp.info.packageName : null,
22493                    intent, resolvedType, resultTo, resultCode, resultData, resultExtras,
22494                    requiredPermissions, appOp, bOptions, serialized, sticky,
22495                    callingPid, callingUid, userId);
22496            Binder.restoreCallingIdentity(origId);
22497            return res;
22498        }
22499    }

broadcastIntent()方法有两个布尔参数serialized和sticky来共同决定是普通广播,有序广播,还是Sticky广播,参数如下:

广播类型.png

ActivityManagerService#broadcastIntentLocked

21730    @GuardedBy("this")
21731    final int broadcastIntentLocked(ProcessRecord callerApp,
21732            String callerPackage, Intent intent, String resolvedType,
21733            IIntentReceiver resultTo, int resultCode, String resultData,
21734            Bundle resultExtras, String[] requiredPermissions, int appOp, Bundle bOptions,
21735            boolean ordered, boolean sticky, int callingPid, int callingUid, int userId) {
21736        intent = new Intent(intent);
21737
21738        final boolean callerInstantApp = isInstantApp(callerApp, callerPackage, callingUid);
21739        // Instant Apps cannot use FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS
21740        if (callerInstantApp) {
21741            intent.setFlags(intent.getFlags() & ~Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS);
21742        }
    // If we have not finished booting, don't allow this to launch new processes.
   //当系统没启动完成时,不允许静态注册的广播起进程响应broadcast
21759        if (!mProcessesReady && (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
21760            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
             
               /**
              5743     * If set, when sending a broadcast only registered receivers will be
              5744     * called -- no BroadcastReceiver components will be launched.
              5745     */
             
21761                 
21755        // By default broadcasts do not go to stopped apps.
21756        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES); 
         //step1: 设置flag
       //这个过程最重要的工作是:
       //添加flag=FLAG_EXCLUDE_STOPPED_PACKAGES,保证已停止app不会收到该广播;
       //当系统还没有启动完成,则不允许启动新进程,即只有动态注册receiver才能接受广播
   
21762
21763        if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG_BROADCAST,
21764                (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
21765                + " ordered=" + ordered + " userid=" + userId);
21766        if ((resultTo != null) && !ordered) {
21767            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
21768        }
21769
21770        userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
21771                ALLOW_NON_FULL, "broadcast", callerPackage);
21772
21773        // Make sure that the user who is receiving this broadcast or its parent is running.
21774        // If not, we will just skip it. Make an exception for shutdown broadcasts, upgrade steps.
21775        if (userId != UserHandle.USER_ALL && !mUserController.isUserOrItsParentRunning(userId)) {
21776            if ((callingUid != SYSTEM_UID
21777                    || (intent.getFlags() & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0)
21778                    && !Intent.ACTION_SHUTDOWN.equals(intent.getAction())) {
21779                Slog.w(TAG, "Skipping broadcast of " + intent
21780                        + ": user " + userId + " and its parent (if any) are stopped");
21781                return ActivityManager.BROADCAST_FAILED_USER_STOPPED;
21782            }
21783        }
           //当非USER_ALL广播且当前用户并没有处于Running的情况下,除非是系统升级广播或者关机广播,否则直接返回。
21784
21785        final String action = intent.getAction();
21786        BroadcastOptions brOptions = null;
21787        if (bOptions != null) {
21788            brOptions = new BroadcastOptions(bOptions);
21789            if (brOptions.getTemporaryAppWhitelistDuration() > 0) {
21790                // See if the caller is allowed to do this.  Note we are checking against
21791                // the actual real caller (not whoever provided the operation as say a
21792                // PendingIntent), because that who is actually supplied the arguments.
21793                if (checkComponentPermission(
21794                        android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST,
21795                        Binder.getCallingPid(), Binder.getCallingUid(), -1, true)
21796                        != PackageManager.PERMISSION_GRANTED) {
21797                    String msg = "Permission Denial: " + intent.getAction()
21798                            + " broadcast from " + callerPackage + " (pid=" + callingPid
21799                            + ", uid=" + callingUid + ")"
21800                            + " requires "
21801                            + android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST;
21802                    Slog.w(TAG, msg);
21803                    throw new SecurityException(msg);
21804                }
21805            }
21806            if (brOptions.isDontSendToRestrictedApps()
21807                    && !isUidActiveLocked(callingUid)
21808                    && isBackgroundRestrictedNoCheck(callingUid, callerPackage)) {
21809                Slog.i(TAG, "Not sending broadcast " + action + " - app " + callerPackage
21810                        + " has background restrictions");
21811                return ActivityManager.START_CANCELED;
21812            }
21813        }
21814
21815        // Verify that protected broadcasts are only being sent by system code,
21816        // and that system code is only sending protected broadcasts.
21817        final boolean isProtectedBroadcast;
21818        try {
21819            isProtectedBroadcast = AppGlobals.getPackageManager().isProtectedBroadcast(action);
21820        } catch (RemoteException e) {
21821            Slog.w(TAG, "Remote exception", e);
21822            return ActivityManager.BROADCAST_SUCCESS;
21823        }
21824
21825        final boolean isCallerSystem;
21826        //step2: 广播权限验证
/*
对于callingAppId为SYSTEM_UID,PHONE_UID,SHELL_UID,BLUETOOTH_UID,NFC_UID之一或者callingUid == 0时都畅通无阻;
否则对于调用者进程为空并且不是persistent进程的情况下:
当发送的是受保护广播mProtectedBroadcasts(只允许系统使用),则抛出异常;
当action为ACTION_APPWIDGET_CONFIGURE时,虽然不希望该应用发送这种广播,处于兼容性考虑,限制该广播只允许发送给自己,否则抛出异常。
*/
21827        final boolean isCallerPersistent = (callerApp != null) && callerApp.persistent;
21828        switch (UserHandle.getAppId(callingUid)) {
21829            case ROOT_UID:
21830            case SYSTEM_UID:
21831            case PHONE_UID:
21832            case BLUETOOTH_UID:
21833            case NFC_UID:
21834            case SE_UID:
21835                isCallerSystem = true;
21836                break;
21837            default:
21838               
21839                //isCallerSystem = (callerApp != null) && callerApp.persistent;
21840                isCallerSystem = false;
21841                break;
21842        }
21843
21844        // First line security check before anything else: stop non-system apps from
21845        // sending protected broadcasts.
21848        if (!isCallerSystem && !isCallerPersistent) {
21849            if (isProtectedBroadcast) {
21850                String msg = "Permission Denial: not allowed to send broadcast "
21851                        + action + " from pid="
21852                        + callingPid + ", uid=" + callingUid;
21853                Slog.w(TAG, msg);
21854                throw new SecurityException(msg);
21855
21856            } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)
21857                    || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)) {
21858                // Special case for compatibility: we don't want apps to send this,
21859                // but historically it has not been protected and apps may be using it
21860                // to poke their own app widget.  So, instead of making it protected,
21861                // just limit it to the caller.
21862                if (callerPackage == null) {
21863                    String msg = "Permission Denial: not allowed to send broadcast "
21864                            + action + " from unknown caller.";
21865                    Slog.w(TAG, msg);
21866                    throw new SecurityException(msg);
21867                } else if (intent.getComponent() != null) {
21868                    // They are good enough to send to an explicit component...  verify
21869                    // it is being sent to the calling app.
21870                    if (!intent.getComponent().getPackageName().equals(
21871                            callerPackage)) {
21872                        String msg = "Permission Denial: not allowed to send broadcast "
21873                                + action + " to "
21874                                + intent.getComponent().getPackageName() + " from "
21875                                + callerPackage;
21876                        Slog.w(TAG, msg);
21877                        throw new SecurityException(msg);
21878                    }
21879                } else {
21880                    // Limit broadcast to their own package.
21881                    intent.setPackage(callerPackage);
21882                }
21883            }
21884        }
21885       //step3: 处理系统相关广播
21886        if (action != null) {
21887            if (getBackgroundLaunchBroadcasts().contains(action)) {
21888                if (DEBUG_BACKGROUND_CHECK) {
21889                    Slog.i(TAG, "Broadcast action " + action + " forcing include-background");
21890                }
21891                intent.addFlags(Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
21892            }
21893
21894            switch (action) {
21895                case Intent.ACTION_UID_REMOVED:
21896                case Intent.ACTION_PACKAGE_REMOVED:
21897                case Intent.ACTION_PACKAGE_CHANGED:
21898                case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
21899                case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
21900                case Intent.ACTION_PACKAGES_SUSPENDED:
21901                case Intent.ACTION_PACKAGES_UNSUSPENDED:
21902                    // Handle special intents: if this broadcast is from the package
21903                    // manager about a package being removed, we need to remove all of
21904                    // its activities from the history stack.
21905                    if (checkComponentPermission(
21906                            android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
21907                            callingPid, callingUid, -1, true)
21908                            != PackageManager.PERMISSION_GRANTED) {
21909                        String msg = "Permission Denial: " + intent.getAction()
21910                                + " broadcast from " + callerPackage + " (pid=" + callingPid
21911                                + ", uid=" + callingUid + ")"
21912                                + " requires "
21913                                + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
21914                        Slog.w(TAG, msg);
21915                        throw new SecurityException(msg);
21916                    }
21917                    switch (action) {
21918                        case Intent.ACTION_UID_REMOVED:
21919                            final int uid = getUidFromIntent(intent);
21920                            if (uid >= 0) {
21921                                mBatteryStatsService.removeUid(uid);
21922                                mAppOpsService.uidRemoved(uid);
21923                            }
21924                            break;
21925                        case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
21926                            // If resources are unavailable just force stop all those packages
21927                            // and flush the attribute cache as well.
21928                            String list[] =
21929                                    intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
21930                            if (list != null && list.length > 0) {
21931                                for (int i = 0; i < list.length; i++) {
21932                                    forceStopPackageLocked(list[i], -1, false, true, true,
21933                                            false, false, userId, "storage unmount");
21934                                }
21935                                mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
21936                                sendPackageBroadcastLocked(
21937                                        ApplicationThreadConstants.EXTERNAL_STORAGE_UNAVAILABLE,
21938                                        list, userId);
21939                            }
21940                            break;
21941                        case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
21942                            mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
21943                            break;
21944                        case Intent.ACTION_PACKAGE_REMOVED:
21945                        case Intent.ACTION_PACKAGE_CHANGED:
21946                            Uri data = intent.getData();
21947                            String ssp;
21948                            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
21949                                boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(action);
21950                                final boolean replacing =
21951                                        intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
21952                                final boolean killProcess =
21953                                        !intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false);
21954                                final boolean fullUninstall = removed && !replacing;
21955                                if (removed) {
21956                                    if (killProcess) {
21957                                        forceStopPackageLocked(ssp, UserHandle.getAppId(
21958                                                intent.getIntExtra(Intent.EXTRA_UID, -1)),
21959                                                false, true, true, false, fullUninstall, userId,
21960                                                removed ? "pkg removed" : "pkg changed");
21961                                    }
21962                                    final int cmd = killProcess
21963                                            ? ApplicationThreadConstants.PACKAGE_REMOVED
21964                                            : ApplicationThreadConstants.PACKAGE_REMOVED_DONT_KILL;
21965                                    sendPackageBroadcastLocked(cmd,
21966                                            new String[] {ssp}, userId);
21967                                    if (fullUninstall) {
21968                                        mAppOpsService.packageRemoved(
21969                                                intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
21970
21971                                        // Remove all permissions granted from/to this package
21972                                        removeUriPermissionsForPackageLocked(ssp, userId, true,
21973                                                false);
21974
21975                                        mRecentTasks.removeTasksByPackageName(ssp, userId);
21976
21977                                        mServices.forceStopPackageLocked(ssp, userId);
21978                                        mAppWarnings.onPackageUninstalled(ssp);
21979                                        mCompatModePackages.handlePackageUninstalledLocked(ssp);
21980                                        mBatteryStatsService.notePackageUninstalled(ssp);
21981                                    }
21982                                } else {
21983                                    if (killProcess) {
21984                                        killPackageProcessesLocked(ssp, UserHandle.getAppId(
21985                                                intent.getIntExtra(Intent.EXTRA_UID, -1)),
21986                                                userId, ProcessList.INVALID_ADJ,
21987                                                false, true, true, false, "change " + ssp);
21988                                    }
21989                                    cleanupDisabledPackageComponentsLocked(ssp, userId, killProcess,
21990                                            intent.getStringArrayExtra(
21991                                                    Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST));
21992                                }
21993                            }
21994                            break;
21995                        case Intent.ACTION_PACKAGES_SUSPENDED:
21996                        case Intent.ACTION_PACKAGES_UNSUSPENDED:
21997                            final boolean suspended = Intent.ACTION_PACKAGES_SUSPENDED.equals(
21998                                    intent.getAction());
21999                            final String[] packageNames = intent.getStringArrayExtra(
22000                                    Intent.EXTRA_CHANGED_PACKAGE_LIST);
22001                            final int userHandle = intent.getIntExtra(
22002                                    Intent.EXTRA_USER_HANDLE, UserHandle.USER_NULL);
22003
22004                            synchronized(ActivityManagerService.this) {
22005                                mRecentTasks.onPackagesSuspendedChanged(
22006                                        packageNames, suspended, userHandle);
22007                            }
22008                            break;
22009                    }
22010                    break;
22011                case Intent.ACTION_PACKAGE_REPLACED:
22012                {
22013                    final Uri data = intent.getData();
22014                    final String ssp;
22015                    if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
22016                        ApplicationInfo aInfo = null;
22017                        try {
22018                            aInfo = AppGlobals.getPackageManager()
22019                                    .getApplicationInfo(ssp, STOCK_PM_FLAGS, userId);
22020                        } catch (RemoteException ignore) {}
22021                        if (aInfo == null) {
22022                            Slog.w(TAG, "Dropping ACTION_PACKAGE_REPLACED for non-existent pkg:"
22023                                    + " ssp=" + ssp + " data=" + data);
22024                            return ActivityManager.BROADCAST_SUCCESS;
22025                        }
22026                        mStackSupervisor.updateActivityApplicationInfoLocked(aInfo);
22027                        mServices.updateServiceApplicationInfoLocked(aInfo);
22028                        sendPackageBroadcastLocked(ApplicationThreadConstants.PACKAGE_REPLACED,
22029                                new String[] {ssp}, userId);
22030                    }
22031                    break;
22032                }
22033                case Intent.ACTION_PACKAGE_ADDED:
22034                {
22035                    // Special case for adding a package: by default turn on compatibility mode.
22036                    Uri data = intent.getData();
22037                    String ssp;
22038                    if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
22039                        final boolean replacing =
22040                                intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
22041                        mCompatModePackages.handlePackageAddedLocked(ssp, replacing);
22042
22043                        try {
22044                            ApplicationInfo ai = AppGlobals.getPackageManager().
22045                                    getApplicationInfo(ssp, STOCK_PM_FLAGS, 0);
22046                            mBatteryStatsService.notePackageInstalled(ssp,
22047                                    ai != null ? ai.versionCode : 0);
22048                        } catch (RemoteException e) {
22049                        }
22050                    }
22051                    break;
22052                }
22053                case Intent.ACTION_PACKAGE_DATA_CLEARED:
22054                {
22055                    Uri data = intent.getData();
22056                    String ssp;
22057                    if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
22058                        mCompatModePackages.handlePackageDataClearedLocked(ssp);
22059                        mAppWarnings.onPackageDataCleared(ssp);
22060                    }
22061                    break;
22062                }
22063                case Intent.ACTION_TIMEZONE_CHANGED:
22064                    // If this is the time zone changed action, queue up a message that will reset
22065                    // the timezone of all currently running processes. This message will get
22066                    // queued up before the broadcast happens.
22067                    mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
22068                    break;
22069                case Intent.ACTION_TIME_CHANGED:
22070                    // EXTRA_TIME_PREF_24_HOUR_FORMAT is optional so we must distinguish between
22071                    // the tri-state value it may contain and "unknown".
22072                    // For convenience we re-use the Intent extra values.
22073                    final int NO_EXTRA_VALUE_FOUND = -1;
22074                    final int timeFormatPreferenceMsgValue = intent.getIntExtra(
22075                            Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT,
22076                            NO_EXTRA_VALUE_FOUND /* defaultValue */);
22077                    // Only send a message if the time preference is available.
22078                    if (timeFormatPreferenceMsgValue != NO_EXTRA_VALUE_FOUND) {
22079                        Message updateTimePreferenceMsg =
22080                                mHandler.obtainMessage(UPDATE_TIME_PREFERENCE_MSG,
22081                                        timeFormatPreferenceMsgValue, 0);
22082                        mHandler.sendMessage(updateTimePreferenceMsg);
22083                    }
22084                    BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
22085                    synchronized (stats) {
22086                        stats.noteCurrentTimeChangedLocked();
22087                    }
22088                    break;
22089                case Intent.ACTION_CLEAR_DNS_CACHE:
22090                    mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
22091                    break;
22092                case Proxy.PROXY_CHANGE_ACTION:
22093                    ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
22094                    mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
22095                    break;
22096                case android.hardware.Camera.ACTION_NEW_PICTURE:
22097                case android.hardware.Camera.ACTION_NEW_VIDEO:
22098                    // In N we just turned these off; in O we are turing them back on partly,
22099                    // only for registered receivers.  This will still address the main problem
22100                    // (a spam of apps waking up when a picture is taken putting significant
22101                    // memory pressure on the system at a bad point), while still allowing apps
22102                    // that are already actively running to know about this happening.
22103                    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
22104                    break;
22105                case android.security.KeyChain.ACTION_TRUST_STORE_CHANGED:
22106                    mHandler.sendEmptyMessage(HANDLE_TRUST_STORAGE_UPDATE_MSG);
22107                    break;
22108                case "com.android.launcher.action.INSTALL_SHORTCUT":
22109                    // As of O, we no longer support this broadcasts, even for pre-O apps.
22110                    // Apps should now be using ShortcutManager.pinRequestShortcut().
22111                    Log.w(TAG, "Broadcast " + action
22112                            + " no longer supported. It will not be delivered.");
22113                    return ActivityManager.BROADCAST_SUCCESS;
22114            }
22115
22116            if (Intent.ACTION_PACKAGE_ADDED.equals(action) ||
22117                    Intent.ACTION_PACKAGE_REMOVED.equals(action) ||
22118                    Intent.ACTION_PACKAGE_REPLACED.equals(action)) {
22119                final int uid = getUidFromIntent(intent);
22120                if (uid != -1) {
22121                    final UidRecord uidRec = mActiveUids.get(uid);
22122                    if (uidRec != null) {
22123                        uidRec.updateHasInternetPermission();
22124                    }
22125                }
22126            }
22127        }
22128
22129        // Add to the sticky list if requested.
             //step4:增加sticky广播
22130        if (sticky) {
22131            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
22132                    callingPid, callingUid)
22133                    != PackageManager.PERMISSION_GRANTED) {
22134                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
22135                        + callingPid + ", uid=" + callingUid
22136                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
22137                Slog.w(TAG, msg);
22138                throw new SecurityException(msg);
22139            }
22140            if (requiredPermissions != null && requiredPermissions.length > 0) {
22141                Slog.w(TAG, "Can't broadcast sticky intent " + intent
22142                        + " and enforce permissions " + Arrays.toString(requiredPermissions));
22143                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
22144            }
22145            if (intent.getComponent() != null) {
22146                throw new SecurityException(
22147                        "Sticky broadcasts can't target a specific component");
22148            }
22149            // We use userId directly here, since the "all" target is maintained
22150            // as a separate set of sticky broadcasts.
22151            if (userId != UserHandle.USER_ALL) {
22152                // But first, if this is not a broadcast to all users, then
22153                // make sure it doesn't conflict with an existing broadcast to
22154                // all users.
22155                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
22156                        UserHandle.USER_ALL);
22157                if (stickies != null) {
22158                    ArrayList<Intent> list = stickies.get(intent.getAction());
22159                    if (list != null) {
22160                        int N = list.size();
22161                        int i;
22162                        for (i=0; i<N; i++) {
22163                            if (intent.filterEquals(list.get(i))) {
22164                                throw new IllegalArgumentException(
22165                                        "Sticky broadcast " + intent + " for user "
22166                                        + userId + " conflicts with existing global broadcast");
22167                            }
22168                        }
22169                    }
22170                }
22171            }
22172            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
22173            if (stickies == null) {
22174                stickies = new ArrayMap<>();
22175                mStickyBroadcasts.put(userId, stickies);
22176            }
22177            ArrayList<Intent> list = stickies.get(intent.getAction());
22178            if (list == null) {
22179                list = new ArrayList<>();
22180                stickies.put(intent.getAction(), list);
22181            }
22182            final int stickiesCount = list.size();
22183            int i;
22184            for (i = 0; i < stickiesCount; i++) {
22185                if (intent.filterEquals(list.get(i))) {
22186                    // This sticky already exists, replace it.
22187                    list.set(i, new Intent(intent));
22188                    break;
22189                }
22190            }
22191            if (i >= stickiesCount) {
22192                list.add(new Intent(intent));
22193            }
22194        }
             //这个过程主要是将sticky广播增加到list,并放入mStickyBroadcasts里面。
22195       //step5:查询receivers和registeredReceivers
22196        int[] users;
22197        if (userId == UserHandle.USER_ALL) {
22198            // Caller wants broadcast to go to all started users.
22199            users = mUserController.getStartedUserArray();//广播给所有已启动用户
22200        } else {
22201            // Caller wants broadcast to go to one specific user.
22202            users = new int[] {userId};//广播给指定用户
22203        }
22204
22205        // Figure out who all will receive this broadcast.
22206        List receivers = null;
22207        List<BroadcastFilter> registeredReceivers = null;
22208        // Need to resolve the intent to interested receivers...
22209        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
22210                 == 0) {
22211            receivers = collectReceiverComponents(intent, resolvedType, callingUid, users);//receivers:记录着匹配当前intent的所有静态注册广播接收者;
22212        }
22213        if (intent.getComponent() == null) {
22214            if (userId == UserHandle.USER_ALL && callingUid == SHELL_UID) {
22215                // Query one target user at a time, excluding shell-restricted users
22216                for (int i = 0; i < users.length; i++) {
22217                    if (mUserController.hasUserRestriction(
22218                            UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) {
22219                        continue;
22220                    }
22221                    List<BroadcastFilter> registeredReceiversForUser =
22222                            mReceiverResolver.queryIntent(intent,
22223                                    resolvedType, false /*defaultOnly*/, users[i]);// 查询动态注册的广播
22224                    if (registeredReceivers == null) {
22225                        registeredReceivers = registeredReceiversForUser;
22226                    } else if (registeredReceiversForUser != null) {
22227                        registeredReceivers.addAll(registeredReceiversForUser);
22228                    }
22229                }
22230            } else {
22231                registeredReceivers = mReceiverResolver.queryIntent(intent,
22232                        resolvedType, false /*defaultOnly*/, userId);//registeredReceivers:记录着匹配当前的所有动态注册的广播接收者
22233            }
22234        }
/*
1119    final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
1120            = new IntentResolver<BroadcastFilter, BroadcastFilter>()

public abstract class IntentResolver<F extends IntentFilter, R extends Object> 
//ReceiverResolver是AMS的成员变量,记录着已注册的广播接收者的resolver.
*/
                  //step6:处理并行广播
22235        //用于标识是否需要用新intent替换旧的intent。
22236        final boolean replacePending =
22237                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
22238
22239        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing broadcast: " + intent.getAction()
22240                + " replacePending=" + replacePending);
22241
22242        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
22243        if (!ordered && NR > 0) { //针对并行广播的情况
22244            // If we are not serializing this broadcast, then send the
22245            // registered receivers separately so they don't wait for the
22246            // components to be launched.
22247            if (isCallerSystem) {
22251                checkBroadcastFromSystem(intent, callerApp, callerPackage, callingUid,
22252                        isProtectedBroadcast, registeredReceivers, requiredPermissions);
22254            }
22255            final BroadcastQueue queue = broadcastQueueForIntent(intent); //根据Intent flag决定是返回前台队列还是后台队列
22256            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
22257                    callerPackage, callingPid, callingUid, callerInstantApp, resolvedType,
22258                    requiredPermissions, appOp, brOptions, registeredReceivers, resultTo,
22259                    resultCode, resultData, resultExtras, ordered, sticky, false, userId); //创建BroadcastRecord
22260            if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing parallel broadcast " + r);
22261            final boolean replaced = replacePending
22262                    && (queue.replaceParallelBroadcastLocked(r) != null); //队列当中已经有这个broadcastRecord了,只不过将其替换为新的,那么就调用replaceParallelBroadcastLocked替换就行了,无需入队enqueueParallelBroadcastLocked,激活处理scheduleBroadcastsLocked的相关操作了
22263            // Note: We assume resultTo is null for non-ordered broadcasts.
22264            if (!replaced) { //无法替换的,入队,进入处理流程
22265                queue.enqueueParallelBroadcastLocked(r);
22266                queue.scheduleBroadcastsLocked();
22267            }
22268            registeredReceivers = null;
22269            NR = 0;
22270        }
22271        //step7:合并registeredReceivers到receivers
22272        // Merge into one list.
22273        int ir = 0;
22274        if (receivers != null) {
22275            // A special case for PACKAGE_ADDED: do not allow the package
22276            // being added to see this broadcast.  This prevents them from
22277            // using this as a back door to get run as soon as they are
22278            // installed.  Maybe in the future we want to have a special install
22279            // broadcast or such for apps, but we'd like to deliberately make
22280            // this decision.
22281            String skipPackages[] = null;
22282            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
22283                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
22284                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
                            //防止应用监听该广播,在安装时直接运行。
22285                Uri data = intent.getData();
22286                if (data != null) {
22287                    String pkgName = data.getSchemeSpecificPart();
22288                    if (pkgName != null) {
22289                        skipPackages = new String[] { pkgName };
22290                    }
22291                }
22292            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
22293                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
22294            }
22295            if (skipPackages != null && (skipPackages.length > 0)) {
22296                for (String skipPackage : skipPackages) {
22297                    if (skipPackage != null) {
22298                        int NT = receivers.size();
22299                        for (int it=0; it<NT; it++) {
22300                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
22301                            if (curt.activityInfo.packageName.equals(skipPackage)) {
22302                                receivers.remove(it);
22303                                it--;
22304                                NT--;
22305                            }
22306                        }
22307                    }
22308                }
22309            }
22310      //将广播相关的静态接收者和动态接收者合并,如果发送的是并行广播,那么就不存在registeredReceivers了,ir==NR
                //对于串行广播,将动态注册的广播接收者队列按照优先级顺序合入到receivers队列
22311            int NT = receivers != null ? receivers.size() : 0; 
22312            int it = 0;
22313            ResolveInfo curt = null;
22314            BroadcastFilter curr = null;
22315            while (it < NT && ir < NR) {
22316                if (curt == null) {
22317                    curt = (ResolveInfo)receivers.get(it);
22318                }
22319                if (curr == null) {
22320                    curr = registeredReceivers.get(ir);
22321                }
22322                if (curr.getPriority() >= curt.priority) {
22323                    // Insert this broadcast record into the final list.
22324                    receivers.add(it, curr);
22325                    ir++;
22326                    curr = null;
22327                    it++;
22328                    NT++;
22329                } else {
22330                    // Skip to the next ResolveInfo in the final list.
22331                    it++;
22332                    curt = null;
22333                }
22334            }
22335        }
22336        while (ir < NR) {
22337            if (receivers == null) {
22338                receivers = new ArrayList();
22339            }
22340            receivers.add(registeredReceivers.get(ir));
22341            ir++;
22342        }
22343
22344        if (isCallerSystem) {
22348            checkBroadcastFromSystem(intent, callerApp, callerPackage, callingUid,
22349                    isProtectedBroadcast, receivers, requiredPermissions);
22351        }
22352       //step8: 处理串行广播
22353        if ((receivers != null && receivers.size() > 0)
22354                || resultTo != null) {
22355            BroadcastQueue queue = broadcastQueueForIntent(intent); //前台queue还是后台queue
22356            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
22357                    callerPackage, callingPid, callingUid, callerInstantApp, resolvedType,
22358                    requiredPermissions, appOp, brOptions, receivers, resultTo, resultCode,
22359                    resultData, resultExtras, ordered, sticky, false, userId);//创建BroadcastRecord
22360 
22361            if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing ordered broadcast " + r
22362                    + ": prev had " + queue.mOrderedBroadcasts.size());
22363            if (DEBUG_BROADCAST) Slog.i(TAG_BROADCAST,
22364                    "Enqueueing broadcast " + r.intent.getAction());
22365
22366            final BroadcastRecord oldRecord =
22367                    replacePending ? queue.replaceOrderedBroadcastLocked(r) : null; 
22368            if (oldRecord != null) {
22369                // Replaced, fire the result-to receiver.
22370                if (oldRecord.resultTo != null) {
22371                    final BroadcastQueue oldQueue = broadcastQueueForIntent(oldRecord.intent);
22372                    try {
22373                        oldQueue.performReceiveLocked(oldRecord.callerApp, oldRecord.resultTo,
22374                                oldRecord.intent,
22375                                Activity.RESULT_CANCELED, null, null,
22376                                false, false, oldRecord.userId); //对于原来就存在的Broadcast
22377                    } catch (RemoteException e) {
22378                        Slog.w(TAG, "Failure ["
22379                                + queue.mQueueName + "] sending broadcast result of "
22380                                + intent, e);
22381
22382                    }
22383                }
22384            } else {
                         //将BroadcastRecord加入到有序广播队列
22385                queue.enqueueOrderedBroadcastLocked(r);
                          //处理广播
22386                queue.scheduleBroadcastsLocked();
22387            }
22388        } else {
22389            // There was nobody interested in the broadcast, but we still want to record
22390            // that it happened.
22391            if (intent.getComponent() == null && intent.getPackage() == null
22392                    && (intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
22393                // This was an implicit broadcast... let's record it for posterity.
                        //对没有接收者的广播,将其保存起来
22394                addBroadcastStatLocked(intent.getAction(), callerPackage, 0, 0, 0);
22395            }
22396        }
22397
22398        return ActivityManager.BROADCAST_SUCCESS;
22399    }
22400

上面的一些逻辑整理

ActivityManagerService#collectReceiverComponents

返回intent对应的静态注册的receiver,通过PMS查找AndroidMainfest中定义的静态广播

21539
21540    private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
21541            int callingUid, int[] users) {
21542        // TODO: come back and remove this assumption to triage all broadcasts
21543        int pmFlags = STOCK_PM_FLAGS | MATCH_DEBUG_TRIAGED_MISSING;
21544
21545        List<ResolveInfo> receivers = null;
21546        try {
21547            HashSet<ComponentName> singleUserReceivers = null;
21548            boolean scannedFirstReceivers = false;
21549            for (int user : users) {
21550                // Skip users that have Shell restrictions, with exception of always permitted
21551                // Shell broadcasts
21552                if (callingUid == SHELL_UID
21553                        && mUserController.hasUserRestriction(
21554                                UserManager.DISALLOW_DEBUGGING_FEATURES, user)
21555                        && !isPermittedShellBroadcast(intent)) {
21556                    continue;
21557                }
21558                List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
21559                        .queryIntentReceivers(intent, resolvedType, pmFlags, user).getList();
21560                if (user != UserHandle.USER_SYSTEM && newReceivers != null) {
21561                    // If this is not the system user, we need to check for
21562                    // any receivers that should be filtered out.
21563                    for (int i=0; i<newReceivers.size(); i++) {
21564                        ResolveInfo ri = newReceivers.get(i);
21565                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SYSTEM_USER_ONLY) != 0) {
21566                            newReceivers.remove(i);
21567                            i--;
21568                        }
21569                    }
21570                }
21571                if (newReceivers != null && newReceivers.size() == 0) {
21572                    newReceivers = null;
21573                }
21574                if (receivers == null) {//用于标识是否需要用新intent替换旧的intent。
21575                    receivers = newReceivers;
21576                } else if (newReceivers != null) {
21577                    // We need to concatenate the additional receivers
21578                    // found with what we have do far.  This would be easy,
21579                    // but we also need to de-dup any receivers that are
21580                    // singleUser.
21581                    if (!scannedFirstReceivers) {
21582                        // Collect any single user receivers we had already retrieved.
21583                        scannedFirstReceivers = true;
21584                        for (int i=0; i<receivers.size(); i++) {
21585                            ResolveInfo ri = receivers.get(i);
21586                            if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
21587                                ComponentName cn = new ComponentName(
21588                                        ri.activityInfo.packageName, ri.activityInfo.name);
21589                                if (singleUserReceivers == null) {
21590                                    singleUserReceivers = new HashSet<ComponentName>();
21591                                }
21592                                singleUserReceivers.add(cn);
21593                            }
21594                        }
21595                    }
21596                    // Add the new results to the existing results, tracking
21597                    // and de-dupping single user receivers.
21598                    for (int i=0; i<newReceivers.size(); i++) {
21599                        ResolveInfo ri = newReceivers.get(i);
21600                        if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
21601                            ComponentName cn = new ComponentName(
21602                                    ri.activityInfo.packageName, ri.activityInfo.name);
21603                            if (singleUserReceivers == null) {
21604                                singleUserReceivers = new HashSet<ComponentName>();
21605                            }
21606                            if (!singleUserReceivers.contains(cn)) {
21607                                singleUserReceivers.add(cn);
21608                                receivers.add(ri);
21609                            }
21610                        } else {
21611                            receivers.add(ri);
21612                        }
21613                    }
21614                }
21615            }
21616        } catch (RemoteException ex) {
21617            // pm is in same process, this will never happen.
21618        }
21619        return receivers;
21620    }

ActivityManagerService#broadcastQueueForIntent

决定是返回前台广播队列还是后台广播队列,根据Intent是否有FLAG_RECEIVER_FOREGROUND来决定

757    BroadcastQueue broadcastQueueForIntent(Intent intent) {
758        final boolean isFg = (intent.getFlags() & Intent.) != 0;
759        if (DEBUG_BROADCAST_BACKGROUND) Slog.i(TAG_BROADCAST,
760                "Broadcast intent " + intent + " on "
761                + (isFg ? "foreground" : "background") + " queue");
762        return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
763    }

BroadcastQueue#replaceParallelBroadcastLocked

245    /**
246     * Find the same intent from queued parallel broadcast, replace with a new one and return
247     * the old one.
248     */
249    public final BroadcastRecord replaceParallelBroadcastLocked(BroadcastRecord r) {
250        return replaceBroadcastLocked(mParallelBroadcasts, r, "PARALLEL");
251    }


261    private BroadcastRecord replaceBroadcastLocked(ArrayList<BroadcastRecord> queue,
262            BroadcastRecord r, String typeForLogging) {
263        final Intent intent = r.intent;
264        for (int i = queue.size() - 1; i > 0; i--) {
265            final BroadcastRecord old = queue.get(i);
266            if (old.userId == r.userId && intent.filterEquals(old.intent)) {
267                if (DEBUG_BROADCAST) {
268                    Slog.v(TAG_BROADCAST, "***** DROPPING "
269                            + typeForLogging + " [" + mQueueName + "]: " + intent);
270                }
271                queue.set(i, r);
272                return old;
273            }
274        }
275        return null;
276    }

BroadcastQueue#enqueueParallelBroadcastLocked

将BroadcastRecord发送到mParallelBroadcasts

221    public void enqueueParallelBroadcastLocked(BroadcastRecord r) {
222        mParallelBroadcasts.add(r);
223        enqueueBroadcastHelper(r);
224    }

广播队列中有一个成员变量mParallelBroadcasts,类型为ArrayList,记录着所有的并行广播

94    /**
95     * Lists of all active broadcasts that are to be executed immediately
96     * (without waiting for another broadcast to finish).  Currently this only
97     * contains broadcasts to registered receivers, to avoid spinning up
98     * a bunch of processes to execute IntentReceiver components.  Background-
99     * and foreground-priority broadcasts are queued separately.
100     */
101    final ArrayList<BroadcastRecord> mParallelBroadcasts = new ArrayList<>();

enqueueBroadcastHelper记录广播入队时间

235    private void enqueueBroadcastHelper(BroadcastRecord r) {
236        r.enqueueClockTime = System.currentTimeMillis(); //记录广播的入队时间
237
238        if (Trace.isTagEnabled(Trace.TRACE_TAG_ACTIVITY_MANAGER)) {
239            Trace.asyncTraceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER,
240                createBroadcastTraceTitle(r, BroadcastRecord.DELIVERY_PENDING),
241                System.identityHashCode(r));
242        }
243    }

从上面的代码,我们知道广播发送方调用sendBroadcast后,AMS会构造对应的BroadcastRecord加入到BroadcastQueue中, 然后调用BroadcastQueue的scheduleBroadcastsLocked函数

BroadcastQueue#scheduleBroadcastsLocked

396    public void scheduleBroadcastsLocked() {
397        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Schedule broadcasts ["
398                + mQueueName + "]: current="
399                + mBroadcastsScheduled);
400         //避免短时间内重复发送BROADCAST_INTENT_MSG
401        if (mBroadcastsScheduled) {
402            return;
403        }
404        mHandler.sendMessage(mHandler.obtainMessage(BROADCAST_INTENT_MSG, this));
405        mBroadcastsScheduled = true;
406    }

mHandler的构造是在BroadcastQueue的构造函数中构造的

mHandler = new BroadcastHandler(handler.getLooper());

203    BroadcastQueue(ActivityManagerService service, Handler handler,
204            String name, long timeoutPeriod, boolean allowDelayBehindServices) {
205        mService = service;
206        mHandler = new BroadcastHandler(handler.getLooper());
207        mQueueName = name;
208        mTimeoutPeriod = timeoutPeriod;
209        mDelayBehindServices = allowDelayBehindServices;
210    }

而BroadcastQueue在AMS的构造函数中构造

3160        mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
3161                "foreground", BROADCAST_FG_TIMEOUT, false);
3162        mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
3163                "background", BROADCAST_BG_TIMEOUT, true);

3137        mHandlerThread = new ServiceThread(TAG,
3138                THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
3139        mHandlerThread.start();
3140        mHandler = new MainHandler(mHandlerThread.getLooper());

创建一个Handler,使用的是ServiceThread的Looper

166    final class BroadcastHandler extends Handler {
167        public BroadcastHandler(Looper looper) {
168            super(looper, null, true);
169        }
170
171        @Override
172        public void handleMessage(Message msg) {
173            switch (msg.what) {
174                case BROADCAST_INTENT_MSG: {
175                    if (DEBUG_BROADCAST) Slog.v(
176                            TAG_BROADCAST, "Received BROADCAST_INTENT_MSG");
177                    processNextBroadcast(true);
178                } break;
179                case BROADCAST_TIMEOUT_MSG: {
180                    synchronized (mService) {
181                        broadcastTimeoutLocked(true);
182                    }
183                } break;
184            }
185        }
186    }

BroadcastQueue#processNextBroadcast

854    //add arg parallelOnce if true, process one broadcast
855    void processNextBroadcast(boolean fromMsg) { 
856        processNextBroadcast(fromMsg, false);
857    }
858
859    void processNextBroadcast(boolean fromMsg, boolean parallelOnce) {
860        synchronized (mService) {
861            processNextBroadcastLocked(fromMsg, false, parallelOnce);
862        }
863    }
864
865    final void processNextBroadcastLocked(boolean fromMsg, boolean skipOomAdj) {
866        processNextBroadcastLocked(fromMsg, skipOomAdj, false);
867    }

Broadcast广播相关的resultTo如何设置

举例:

163        mContext.sendOrderedBroadcastAsUser(completeIntent, managedProfileUserHandle, null,
164                dpcReceivedSuccessReceiver, null, Activity.RESULT_OK, null, null);
2254    /**
2255     * Version of
2256     * {@link #sendOrderedBroadcast(Intent, String, BroadcastReceiver, Handler, int, String, Bundle)}
2257     * that allows you to specify the
2258     * user the broadcast will be sent to.  This is not available to applications
2259     * that are not pre-installed on the system image.
2260     *
2261     * <p>See {@link BroadcastReceiver} for more information on Intent broadcasts.
2262     *
2263     * @param intent The Intent to broadcast; all receivers matching this
2264     *               Intent will receive the broadcast.
2265     * @param user UserHandle to send the intent to.
2266     * @param receiverPermission String naming a permissions that
2267     *               a receiver must hold in order to receive your broadcast.
2268     *               If null, no permission is required.
2269     * @param resultReceiver Your own BroadcastReceiver to treat as the final
2270     *                       receiver of the broadcast.
2271     * @param scheduler A custom Handler with which to schedule the
2272     *                  resultReceiver callback; if null it will be
2273     *                  scheduled in the Context's main thread.
2274     * @param initialCode An initial value for the result code.  Often
2275     *                    Activity.RESULT_OK.
2276     * @param initialData An initial value for the result data.  Often
2277     *                    null.
2278     * @param initialExtras An initial value for the result extras.  Often
2279     *                      null.
2280     *
2281     * @see #sendOrderedBroadcast(Intent, String, BroadcastReceiver, Handler, int, String, Bundle)
2282     */
2283    @RequiresPermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
2284    public abstract void sendOrderedBroadcastAsUser(@RequiresPermission Intent intent,
2285            UserHandle user, @Nullable String receiverPermission, BroadcastReceiver resultReceiver,
2286            @Nullable Handler scheduler, int initialCode, @Nullable String initialData,
2287            @Nullable  Bundle initialExtras);

注意,这里是发送的流程,其中的rd就代表动态注册的resultTo receiver

1259    @Override
1260    public void sendOrderedBroadcastAsUser(Intent intent, UserHandle user,
1261            String receiverPermission, int appOp, Bundle options, BroadcastReceiver resultReceiver,
1262            Handler scheduler, int initialCode, String initialData, Bundle initialExtras) {
1263        IIntentReceiver rd = null;
1264        if (resultReceiver != null) {
1265            if (mPackageInfo != null) {
1266                if (scheduler == null) {
1267                    scheduler = mMainThread.getHandler();
1268                }
1269                rd = mPackageInfo.getReceiverDispatcher(
1270                    resultReceiver, getOuterContext(), scheduler,
1271                    mMainThread.getInstrumentation(), false);
1272            } else {
1273                if (scheduler == null) {
1274                    scheduler = mMainThread.getHandler();
1275                }
1276                rd = new LoadedApk.ReceiverDispatcher(resultReceiver, getOuterContext(),
1277                        scheduler, null, false).getIIntentReceiver();
1278            }
1279        }
1280        String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
1281        String[] receiverPermissions = receiverPermission == null ? null
1282                : new String[] {receiverPermission};
1283        try {
1284            intent.prepareToLeaveProcess(this);
1285            ActivityManager.getService().broadcastIntent(
1286                mMainThread.getApplicationThread(), intent, resolvedType, rd,
1287                initialCode, initialData, initialExtras, receiverPermissions,
1288                    appOp, options, true, false, user.getIdentifier());
1289        } catch (RemoteException e) {
1290            throw e.rethrowFromSystemServer();
1291        }
1292    }
send Broadcast.png

调用到processNextBroadcast,这个流程较为复杂,单独写一章梳理相关流程

上一篇下一篇

猜你喜欢

热点阅读