• BroadcastReceiver的工作原理【转】


    这里主要跟一下android源码,看看BroadcastReceiver的工作原理。BroadcastReceiver分动态注册和静态注册,静态注册涉及到系统开机时的程序安装过程,这里关于静态注册BroadcastReceiver的过程暂时不理,等写到程序安装会有相应的解说。

    我们将从普通的Activity.registerReceiver开始:

    @Override
     public Intent registerReceiver(
          BroadcastReceiver receiver, IntentFilter filter) {
            return mBase.registerReceiver(receiver, filter);
        }
    1410    @Override
    1411    public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter) {
    1412        return registerReceiver(receiver, filter, null, null);
    1413    }
    1414
    1415    @Override
    1416    public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter,
    1417            String broadcastPermission, Handler scheduler) {
    1418        return registerReceiverInternal(receiver, getUserId(),
    1419                filter, broadcastPermission, scheduler, getOuterContext());
    1420    }
    1421
    1422    @Override
    1423    public Intent registerReceiverAsUser(BroadcastReceiver receiver, UserHandle user,
    1424            IntentFilter filter, String broadcastPermission, Handler scheduler) {
    1425        return registerReceiverInternal(receiver, user.getIdentifier(),
    1426                filter, broadcastPermission, scheduler, getOuterContext());
    1427    }
    
    1628    private Intent registerReceiverInternal(BroadcastReceiver receiver, int userId,
    1629            IntentFilter filter, String broadcastPermission,
    1630            Handler scheduler, Context context) {
    1631        IIntentReceiver rd = null;
    1632        if (receiver != null) {
    1633            if (mPackageInfo != null && context != null) {
    1634                if (scheduler == null) {
    1635                    scheduler = mMainThread.getHandler();//如果没有传入Handler scheduler 默认是mMainThread.getHandler()
    1636                }
    1637                rd = mPackageInfo.getReceiverDispatcher(
    1638                    receiver, context, scheduler,
    1639                    mMainThread.getInstrumentation(), true); 
    1640            } else {
    1641                if (scheduler == null) {
    1642                    scheduler = mMainThread.getHandler();//如果没有传入Handler scheduler 默认是mMainThread.getHandler()
    1643                }
    1644                rd = new LoadedApk.ReceiverDispatcher(
    1645                        receiver, context, scheduler, null, true).getIIntentReceiver();
    1646            }
    1647        }
    1648        try {
    1649            return ActivityManagerNative.getDefault().registerReceiver(//注册到
    1650                    mMainThread.getApplicationThread(), mBasePackageName,
    1651                    rd, filter, broadcastPermission, userId);
    1652        } catch (RemoteException e) {
    1653            return null;
    1654        }
    1655    }

    1、Activity继承自ContextWrapper,Activity.registerReceiver最终会跳转到ActivityManagerNative.registerReceiver,中间值得注意的是Handler scheduler,回调的线程调度,这是一个可选的参数,如果不设或者设置为空,默认是主线程。这里会新建一个LoadedApk.ReceiverDispatcher,用于保存receiver+scheduler信息。

    12764    public Intent registerReceiver(IApplicationThread caller, String callerPackage,
    12765            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
    12766        enforceNotIsolatedCaller("registerReceiver");
    12767        int callingUid;
    12768        int callingPid;
    12769        synchronized(this) {
    12770            ProcessRecord callerApp = null;
    12771            if (caller != null) {
    12772                callerApp = getRecordForAppLocked(caller);
    12773                if (callerApp == null) {
    12774                    throw new SecurityException(
    12775                            "Unable to find app for caller " + caller
    12776                            + " (pid=" + Binder.getCallingPid()
    12777                            + ") when registering receiver " + receiver);
    12778                }
    12779                if (callerApp.info.uid != Process.SYSTEM_UID &&
    12780                        !callerApp.pkgList.containsKey(callerPackage)) {
    12781                    throw new SecurityException("Given caller package " + callerPackage
    12782                            + " is not running in process " + callerApp);
    12783                }
    12784                callingUid = callerApp.info.uid;
    12785                callingPid = callerApp.pid;
    12786            } else {
    12787                callerPackage = null;
    12788                callingUid = Binder.getCallingUid();
    12789                callingPid = Binder.getCallingPid();
    12790            }
    12791
    12792            userId = this.handleIncomingUser(callingPid, callingUid, userId,
    12793                    true, true, "registerReceiver", callerPackage);
    12794
    12795            List allSticky = null;
    12796
    12797            // Look for any matching sticky broadcasts...
    12798            Iterator actions = filter.actionsIterator();
    12799            if (actions != null) {
    12800                while (actions.hasNext()) {
    12801                    String action = (String)actions.next();
    12802                    allSticky = getStickiesLocked(action, filter, allSticky,
    12803                            UserHandle.USER_ALL);
    12804                    allSticky = getStickiesLocked(action, filter, allSticky,
    12805                            UserHandle.getUserId(callingUid));
    12806                }
    12807            } else {
    12808                allSticky = getStickiesLocked(null, filter, allSticky,
    12809                        UserHandle.USER_ALL);
    12810                allSticky = getStickiesLocked(null, filter, allSticky,
    12811                        UserHandle.getUserId(callingUid));
    12812            }
    12813
    12814            // The first sticky in the list is returned directly back to
    12815            // the client.
    12816            Intent sticky = allSticky != null ? (Intent)allSticky.get(0) : null;
    12817
    12818            if (DEBUG_BROADCAST) Slog.v(TAG, "Register receiver " + filter
    12819                    + ": " + sticky);
    12820
    12821            if (receiver == null) {
    12822                return sticky;
    12823            }
    12824
    12825            ReceiverList rl
    12826                = (ReceiverList)mRegisteredReceivers.get(receiver.asBinder());
    12827            if (rl == null) {
    12828                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
    12829                        userId, receiver);
    12830                if (rl.app != null) {
    12831                    rl.app.receivers.add(rl);
    12832                } else {
    12833                    try {
    12834                        receiver.asBinder().linkToDeath(rl, 0);
    12835                    } catch (RemoteException e) {
    12836                        return sticky;
    12837                    }
    12838                    rl.linkedToDeath = true;
    12839                }
    12840                mRegisteredReceivers.put(receiver.asBinder(), rl);//注册到HashMap
    12841            } else if (rl.uid != callingUid) {
    12842                throw new IllegalArgumentException(
    12843                        "Receiver requested to register for uid " + callingUid
    12844                        + " was previously registered for uid " + rl.uid);
    12845            } else if (rl.pid != callingPid) {
    12846                throw new IllegalArgumentException(
    12847                        "Receiver requested to register for pid " + callingPid
    12848                        + " was previously registered for pid " + rl.pid);
    12849            } else if (rl.userId != userId) {
    12850                throw new IllegalArgumentException(
    12851                        "Receiver requested to register for user " + userId
    12852                        + " was previously registered for user " + rl.userId);
    12853            }
    12854            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
    12855                    permission, callingUid, userId);
    12856            rl.add(bf);
    12857            if (!bf.debugCheck()) {
    12858                Slog.w(TAG, "==> For Dynamic broadast");
    12859            }
    12860            mReceiverResolver.addFilter(bf);
    12861
    12862            // Enqueue broadcasts for all existing stickies that match
    12863            // this filter.
    12864            if (allSticky != null) {
    12865                ArrayList receivers = new ArrayList();
    12866                receivers.add(bf);
    12867
    12868                int N = allSticky.size();
    12869                for (int i=0; i<N; i++) {
    12870                    Intent intent = (Intent)allSticky.get(i);
    12871                    BroadcastQueue queue = broadcastQueueForIntent(intent);
    12872                    BroadcastRecord r = new BroadcastRecord(queue, intent, null,
    12873                            null, -1, -1, null, null, AppOpsManager.OP_NONE, receivers, null, 0,
    12874                            null, null, false, true, true, -1);
    12875                    queue.enqueueParallelBroadcastLocked(r);
    12876                    queue.scheduleBroadcastsLocked();
    12877                }
    12878            }
    12879
    12880            return sticky;
    12881        }
    12882    }

    2、主要看12840:mRegisteredReceivers.put(receiver.asBinder(), rl);queue.enqueueParallelBroadcastLocked(r);//receiver注册到HashMap,receiver被封装成dispatcher注册到BroadcastQueue,到这里BroadcastReceiver的注册基本完毕。

    我们从普通的Activity.sendBroadcast继续:

    1129    @Override
    1130    public void sendBroadcast(Intent intent) {
    1131        warnIfCallingFromSystemProcess();
    1132        String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
    1133        try {
    1134            intent.prepareToLeaveProcess();
    1135            ActivityManagerNative.getDefault().broadcastIntent(
    1136                mMainThread.getApplicationThread(), intent, resolvedType, null,
    1137                Activity.RESULT_OK, null, null, null, AppOpsManager.OP_NONE, false, false,
    1138                getUserId());
    1139        } catch (RemoteException e) {
    1140        }
    1141    }
    13444    public final int broadcastIntent(IApplicationThread caller,
    13445            Intent intent, String resolvedType, IIntentReceiver resultTo,
    13446            int resultCode, String resultData, Bundle map,
    13447            String requiredPermission, int appOp, boolean serialized, boolean sticky, int userId) {
    13448        enforceNotIsolatedCaller("broadcastIntent");
    13449        synchronized(this) {
    13450            intent = verifyBroadcastLocked(intent);
    13451            
    13452            final ProcessRecord callerApp = getRecordForAppLocked(caller);
    13453            final int callingPid = Binder.getCallingPid();
    13454            final int callingUid = Binder.getCallingUid();
    13455            final long origId = Binder.clearCallingIdentity();
    13456            int res = broadcastIntentLocked(callerApp,
    13457                    callerApp != null ? callerApp.info.packageName : null,
    13458                    intent, resolvedType, resultTo,
    13459                    resultCode, resultData, map, requiredPermission, appOp, serialized, sticky,
    13460                    callingPid, callingUid, userId);
    13461            Binder.restoreCallingIdentity(origId);
    13462            return res;
    13463        }
    13464    }
    
    13019    private final int broadcastIntentLocked(ProcessRecord callerApp,
    13020            String callerPackage, Intent intent, String resolvedType,
    13021            IIntentReceiver resultTo, int resultCode, String resultData,
    13022            Bundle map, String requiredPermission, int appOp,
    13023            boolean ordered, boolean sticky, int callingPid, int callingUid,
    13024            int userId) {
    13025        intent = new Intent(intent);
    13026
    13027        // By default broadcasts do not go to stopped apps.
    13028        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
    13029
    13030        if (DEBUG_BROADCAST_LIGHT) Slog.v(
    13031            TAG, (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
    13032            + " ordered=" + ordered + " userid=" + userId);
    13033        if ((resultTo != null) && !ordered) {
    13034            Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
    13035        }
    13036
    13037        userId = handleIncomingUser(callingPid, callingUid, userId,
    13038                true, false, "broadcast", callerPackage);
    13039
    13040        // Make sure that the user who is receiving this broadcast is started.
    13041        // If not, we will just skip it.
    13042        if (userId != UserHandle.USER_ALL && mStartedUsers.get(userId) == null) {
    13043            if (callingUid != Process.SYSTEM_UID || (intent.getFlags()
    13044                    & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
    13045                Slog.w(TAG, "Skipping broadcast of " + intent
    13046                        + ": user " + userId + " is stopped");
    13047                return ActivityManager.BROADCAST_SUCCESS;
    13048            }
    13049        }
    13050
    13051        /*
    13052         * Prevent non-system code (defined here to be non-persistent
    13053         * processes) from sending protected broadcasts.
    13054         */
    13055        int callingAppId = UserHandle.getAppId(callingUid);
    13056        if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID
    13057            || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID ||
    13058            callingUid == 0) {
    13059            // Always okay.
    13060        } else if (callerApp == null || !callerApp.persistent) {
    13061            try {
    13062                if (AppGlobals.getPackageManager().isProtectedBroadcast(
    13063                        intent.getAction())) {
    13064                    String msg = "Permission Denial: not allowed to send broadcast "
    13065                            + intent.getAction() + " from pid="
    13066                            + callingPid + ", uid=" + callingUid;
    13067                    Slog.w(TAG, msg);
    13068                    throw new SecurityException(msg);
    13069                } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) {
    13070                    // Special case for compatibility: we don't want apps to send this,
    13071                    // but historically it has not been protected and apps may be using it
    13072                    // to poke their own app widget.  So, instead of making it protected,
    13073                    // just limit it to the caller.
    13074                    if (callerApp == null) {
    13075                        String msg = "Permission Denial: not allowed to send broadcast "
    13076                                + intent.getAction() + " from unknown caller.";
    13077                        Slog.w(TAG, msg);
    13078                        throw new SecurityException(msg);
    13079                    } else if (intent.getComponent() != null) {
    13080                        // They are good enough to send to an explicit component...  verify
    13081                        // it is being sent to the calling app.
    13082                        if (!intent.getComponent().getPackageName().equals(
    13083                                callerApp.info.packageName)) {
    13084                            String msg = "Permission Denial: not allowed to send broadcast "
    13085                                    + intent.getAction() + " to "
    13086                                    + intent.getComponent().getPackageName() + " from "
    13087                                    + callerApp.info.packageName;
    13088                            Slog.w(TAG, msg);
    13089                            throw new SecurityException(msg);
    13090                        }
    13091                    } else {
    13092                        // Limit broadcast to their own package.
    13093                        intent.setPackage(callerApp.info.packageName);
    13094                    }
    13095                }
    13096            } catch (RemoteException e) {
    13097                Slog.w(TAG, "Remote exception", e);
    13098                return ActivityManager.BROADCAST_SUCCESS;
    13099            }
    13100        }
    13101
    13102        // Handle special intents: if this broadcast is from the package
    13103        // manager about a package being removed, we need to remove all of
    13104        // its activities from the history stack.
    13105        final boolean uidRemoved = Intent.ACTION_UID_REMOVED.equals(
    13106                intent.getAction());
    13107        if (Intent.ACTION_PACKAGE_REMOVED.equals(intent.getAction())
    13108                || Intent.ACTION_PACKAGE_CHANGED.equals(intent.getAction())
    13109                || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())
    13110                || uidRemoved) {
    13111            if (checkComponentPermission(
    13112                    android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
    13113                    callingPid, callingUid, -1, true)
    13114                    == PackageManager.PERMISSION_GRANTED) {
    13115                if (uidRemoved) {
    13116                    final Bundle intentExtras = intent.getExtras();
    13117                    final int uid = intentExtras != null
    13118                            ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
    13119                    if (uid >= 0) {
    13120                        BatteryStatsImpl bs = mBatteryStatsService.getActiveStatistics();
    13121                        synchronized (bs) {
    13122                            bs.removeUidStatsLocked(uid);
    13123                        }
    13124                        mAppOpsService.uidRemoved(uid);
    13125                    }
    13126                } else {
    13127                    // If resources are unavailable just force stop all
    13128                    // those packages and flush the attribute cache as well.
    13129                    if (Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(intent.getAction())) {
    13130                        String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
    13131                        if (list != null && (list.length > 0)) {
    13132                            for (String pkg : list) {
    13133                                forceStopPackageLocked(pkg, -1, false, true, true, false, userId,
    13134                                        "storage unmount");
    13135                            }
    13136                            sendPackageBroadcastLocked(
    13137                                    IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list, userId);
    13138                        }
    13139                    } else {
    13140                        Uri data = intent.getData();
    13141                        String ssp;
    13142                        if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
    13143                            boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(
    13144                                    intent.getAction());
    13145                            if (!intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false)) {
    13146                                forceStopPackageLocked(ssp, UserHandle.getAppId(
    13147                                        intent.getIntExtra(Intent.EXTRA_UID, -1)), false, true, true,
    13148                                        false, userId, removed ? "pkg removed" : "pkg changed");
    13149                            }
    13150                            if (removed) {
    13151                                sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,
    13152                                        new String[] {ssp}, userId);
    13153                                if (!intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) {
    13154                                    mAppOpsService.packageRemoved(
    13155                                            intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
    13156
    13157                                    // Remove all permissions granted from/to this package
    13158                                    removeUriPermissionsForPackageLocked(ssp, userId, true);
    13159                                }
    13160                            }
    13161                        }
    13162                    }
    13163                }
    13164            } else {
    13165                String msg = "Permission Denial: " + intent.getAction()
    13166                        + " broadcast from " + callerPackage + " (pid=" + callingPid
    13167                        + ", uid=" + callingUid + ")"
    13168                        + " requires "
    13169                        + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
    13170                Slog.w(TAG, msg);
    13171                throw new SecurityException(msg);
    13172            }
    13173
    13174        // Special case for adding a package: by default turn on compatibility
    13175        // mode.
    13176        } else if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())) {
    13177            Uri data = intent.getData();
    13178            String ssp;
    13179            if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
    13180                mCompatModePackages.handlePackageAddedLocked(ssp,
    13181                        intent.getBooleanExtra(Intent.EXTRA_REPLACING, false));
    13182            }
    13183        }
    13184
    13185        /*
    13186         * If this is the time zone changed action, queue up a message that will reset the timezone
    13187         * of all currently running processes. This message will get queued up before the broadcast
    13188         * happens.
    13189         */
    13190        if (intent.ACTION_TIMEZONE_CHANGED.equals(intent.getAction())) {
    13191            mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
    13192        }
    13193
    13194        if (intent.ACTION_CLEAR_DNS_CACHE.equals(intent.getAction())) {
    13195            mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
    13196        }
    13197
    13198        if (Proxy.PROXY_CHANGE_ACTION.equals(intent.getAction())) {
    13199            ProxyProperties proxy = intent.getParcelableExtra("proxy");
    13200            mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
    13201        }
    13202
    13203        // Add to the sticky list if requested.
    13204        if (sticky) {
    13205            if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
    13206                    callingPid, callingUid)
    13207                    != PackageManager.PERMISSION_GRANTED) {
    13208                String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
    13209                        + callingPid + ", uid=" + callingUid
    13210                        + " requires " + android.Manifest.permission.BROADCAST_STICKY;
    13211                Slog.w(TAG, msg);
    13212                throw new SecurityException(msg);
    13213            }
    13214            if (requiredPermission != null) {
    13215                Slog.w(TAG, "Can't broadcast sticky intent " + intent
    13216                        + " and enforce permission " + requiredPermission);
    13217                return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
    13218            }
    13219            if (intent.getComponent() != null) {
    13220                throw new SecurityException(
    13221                        "Sticky broadcasts can't target a specific component");
    13222            }
    13223            // We use userId directly here, since the "all" target is maintained
    13224            // as a separate set of sticky broadcasts.
    13225            if (userId != UserHandle.USER_ALL) {
    13226                // But first, if this is not a broadcast to all users, then
    13227                // make sure it doesn't conflict with an existing broadcast to
    13228                // all users.
    13229                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
    13230                        UserHandle.USER_ALL);
    13231                if (stickies != null) {
    13232                    ArrayList<Intent> list = stickies.get(intent.getAction());
    13233                    if (list != null) {
    13234                        int N = list.size();
    13235                        int i;
    13236                        for (i=0; i<N; i++) {
    13237                            if (intent.filterEquals(list.get(i))) {
    13238                                throw new IllegalArgumentException(
    13239                                        "Sticky broadcast " + intent + " for user "
    13240                                        + userId + " conflicts with existing global broadcast");
    13241                            }
    13242                        }
    13243                    }
    13244                }
    13245            }
    13246            ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
    13247            if (stickies == null) {
    13248                stickies = new ArrayMap<String, ArrayList<Intent>>();
    13249                mStickyBroadcasts.put(userId, stickies);
    13250            }
    13251            ArrayList<Intent> list = stickies.get(intent.getAction());
    13252            if (list == null) {
    13253                list = new ArrayList<Intent>();
    13254                stickies.put(intent.getAction(), list);
    13255            }
    13256            int N = list.size();
    13257            int i;
    13258            for (i=0; i<N; i++) {
    13259                if (intent.filterEquals(list.get(i))) {
    13260                    // This sticky already exists, replace it.
    13261                    list.set(i, new Intent(intent));
    13262                    break;
    13263                }
    13264            }
    13265            if (i >= N) {
    13266                list.add(new Intent(intent));
    13267            }
    13268        }
    13269
    13270        int[] users;
    13271        if (userId == UserHandle.USER_ALL) {
    13272            // Caller wants broadcast to go to all started users.
    13273            users = mStartedUserArray;
    13274        } else {
    13275            // Caller wants broadcast to go to one specific user.
    13276            users = new int[] {userId};
    13277        }
    13278
    13279        // Figure out who all will receive this broadcast.
    13280        List receivers = null;
    13281        List<BroadcastFilter> registeredReceivers = null;
    13282        // Need to resolve the intent to interested receivers...
    13283        if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
    13284                 == 0) {
    13285            receivers = collectReceiverComponents(intent, resolvedType, users);
    13286        }
    13287        if (intent.getComponent() == null) {
    13288            registeredReceivers = mReceiverResolver.queryIntent(intent,
    13289                    resolvedType, false, userId);
    13290        }
    13291
    13292        final boolean replacePending =
    13293                (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
    13294        
    13295        if (DEBUG_BROADCAST) Slog.v(TAG, "Enqueing broadcast: " + intent.getAction()
    13296                + " replacePending=" + replacePending);
    13297        
    13298        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
    13299        if (!ordered && NR > 0) {
    13300            // If we are not serializing this broadcast, then send the
    13301            // registered receivers separately so they don't wait for the
    13302            // components to be launched.
    13303            final BroadcastQueue queue = broadcastQueueForIntent(intent);
    13304            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
    13305                    callerPackage, callingPid, callingUid, resolvedType, requiredPermission,
    13306                    appOp, registeredReceivers, resultTo, resultCode, resultData, map,
    13307                    ordered, sticky, false, userId);
    13308            if (DEBUG_BROADCAST) Slog.v(
    13309                    TAG, "Enqueueing parallel broadcast " + r);
    13310            final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
    13311            if (!replaced) {
    13312                queue.enqueueParallelBroadcastLocked(r);
    13313                queue.scheduleBroadcastsLocked();
    13314            }
    13315            registeredReceivers = null;
    13316            NR = 0;
    13317        }
    13318
    13319        // Merge into one list.
    13320        int ir = 0;
    13321        if (receivers != null) {
    13322            // A special case for PACKAGE_ADDED: do not allow the package
    13323            // being added to see this broadcast.  This prevents them from
    13324            // using this as a back door to get run as soon as they are
    13325            // installed.  Maybe in the future we want to have a special install
    13326            // broadcast or such for apps, but we'd like to deliberately make
    13327            // this decision.
    13328            String skipPackages[] = null;
    13329            if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
    13330                    || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
    13331                    || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
    13332                Uri data = intent.getData();
    13333                if (data != null) {
    13334                    String pkgName = data.getSchemeSpecificPart();
    13335                    if (pkgName != null) {
    13336                        skipPackages = new String[] { pkgName };
    13337                    }
    13338                }
    13339            } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
    13340                skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
    13341            }
    13342            if (skipPackages != null && (skipPackages.length > 0)) {
    13343                for (String skipPackage : skipPackages) {
    13344                    if (skipPackage != null) {
    13345                        int NT = receivers.size();
    13346                        for (int it=0; it<NT; it++) {
    13347                            ResolveInfo curt = (ResolveInfo)receivers.get(it);
    13348                            if (curt.activityInfo.packageName.equals(skipPackage)) {
    13349                                receivers.remove(it);
    13350                                it--;
    13351                                NT--;
    13352                            }
    13353                        }
    13354                    }
    13355                }
    13356            }
    13357
    13358            int NT = receivers != null ? receivers.size() : 0;
    13359            int it = 0;
    13360            ResolveInfo curt = null;
    13361            BroadcastFilter curr = null;
    13362            while (it < NT && ir < NR) {
    13363                if (curt == null) {
    13364                    curt = (ResolveInfo)receivers.get(it);
    13365                }
    13366                if (curr == null) {
    13367                    curr = registeredReceivers.get(ir);
    13368                }
    13369                if (curr.getPriority() >= curt.priority) {
    13370                    // Insert this broadcast record into the final list.
    13371                    receivers.add(it, curr);
    13372                    ir++;
    13373                    curr = null;
    13374                    it++;
    13375                    NT++;
    13376                } else {
    13377                    // Skip to the next ResolveInfo in the final list.
    13378                    it++;
    13379                    curt = null;
    13380                }
    13381            }
    13382        }
    13383        while (ir < NR) {
    13384            if (receivers == null) {
    13385                receivers = new ArrayList();
    13386            }
    13387            receivers.add(registeredReceivers.get(ir));
    13388            ir++;
    13389        }
    13390
    13391        if ((receivers != null && receivers.size() > 0)
    13392                || resultTo != null) {
    13393            BroadcastQueue queue = broadcastQueueForIntent(intent);
    13394            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
    13395                    callerPackage, callingPid, callingUid, resolvedType,
    13396                    requiredPermission, appOp, receivers, resultTo, resultCode,
    13397                    resultData, map, ordered, sticky, false, userId);
    13398            if (DEBUG_BROADCAST) Slog.v(
    13399                    TAG, "Enqueueing ordered broadcast " + r
    13400                    + ": prev had " + queue.mOrderedBroadcasts.size());
    13401            if (DEBUG_BROADCAST) {
    13402                int seq = r.intent.getIntExtra("seq", -1);
    13403                Slog.i(TAG, "Enqueueing broadcast " + r.intent.getAction() + " seq=" + seq);
    13404            }
    13405            boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r); 
    13406            if (!replaced) {
    13407                queue.enqueueOrderedBroadcastLocked(r);
    13408                queue.scheduleBroadcastsLocked();
    13409            }
    13410        }
    13411
    13412        return ActivityManager.BROADCAST_SUCCESS;
    13413    }
    </pre>
    </div>
    <p>  </p>
    <div class="cnblogs_Highlighter">
    <pre class="brush:java;gutter:true;">//com.android.server.am.BroadcastQueue.java
    312     public void scheduleBroadcastsLocked() {
    313         if (DEBUG_BROADCAST) Slog.v(TAG, "Schedule broadcasts ["
    314                 + mQueueName + "]: current="
    315                 + mBroadcastsScheduled);
    316 
    317         if (mBroadcastsScheduled) {
    318             return;
    319         }
    320         mHandler.sendMessage(mHandler.obtainMessage(BROADCAST_INTENT_MSG, this));
    321         mBroadcastsScheduled = true;
    322     }
    
    134     final Handler mHandler = new Handler() {
    135         public void handleMessage(Message msg) {
    136             switch (msg.what) {
    137                 case BROADCAST_INTENT_MSG: {
    138                     if (DEBUG_BROADCAST) Slog.v(
    139                             TAG, "Received BROADCAST_INTENT_MSG");
    140                     processNextBroadcast(true);
    141                 } break;
    142                 case BROADCAST_TIMEOUT_MSG: {
    143                     synchronized (mService) {
    144                         broadcastTimeoutLocked(true);
    145                     }
    146                 } break;
    147             }
    148         }
    149     };
    
    525     final void processNextBroadcast(boolean fromMsg) {
    526         synchronized(mService) {
    527             BroadcastRecord r;
    528 
    529             if (DEBUG_BROADCAST) Slog.v(TAG, "processNextBroadcast ["
    530                     + mQueueName + "]: "
    531                     + mParallelBroadcasts.size() + " broadcasts, "
    532                     + mOrderedBroadcasts.size() + " ordered broadcasts");
    533 
    534             mService.updateCpuStats();
    535 
    536             if (fromMsg) {
    537                 mBroadcastsScheduled = false;
    538             }
    539 
    540             // First, deliver any non-serialized broadcasts right away.
    541             while (mParallelBroadcasts.size() &gt; 0) {
    542                 r = mParallelBroadcasts.remove(0);
    543                 r.dispatchTime = SystemClock.uptimeMillis();
    544                 r.dispatchClockTime = System.currentTimeMillis();
    545                 final int N = r.receivers.size();
    546                 if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG, "Processing parallel broadcast ["
    547                         + mQueueName + "] " + r);
    548                 for (int i=0; i&lt;N; i++) {
    549                     Object target = r.receivers.get(i);
    550                     if (DEBUG_BROADCAST)  Slog.v(TAG,
    551                             "Delivering non-ordered on [" + mQueueName + "] to registered "
    552                             + target + ": " + r);
    553                     deliverToRegisteredReceiverLocked(r, (BroadcastFilter)target, false);
    554                 }
    555                 addBroadcastToHistoryLocked(r);
    556                 if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG, "Done with parallel broadcast ["
    557                         + mQueueName + "] " + r);
    558             }
    559 
    560             // Now take care of the next serialized one...
    561 
    562             // If we are waiting for a process to come up to handle the next
    563             // broadcast, then do nothing at this point.  Just in case, we
    564             // check that the process we're waiting for still exists.
    565             if (mPendingBroadcast != null) {
    566                 if (DEBUG_BROADCAST_LIGHT) {
    567                     Slog.v(TAG, "processNextBroadcast ["
    568                             + mQueueName + "]: waiting for "
    569                             + mPendingBroadcast.curApp);
    570                 }
    571 
    572                 boolean isDead;
    573                 synchronized (mService.mPidsSelfLocked) {
    574                     ProcessRecord proc = mService.mPidsSelfLocked.get(mPendingBroadcast.curApp.pid);
    575                     isDead = proc == null || proc.crashing;
    576                 }
    577                 if (!isDead) {
    578                     // It's still alive, so keep waiting
    579                     return;
    580                 } else {
    581                     Slog.w(TAG, "pending app  ["
    582                             + mQueueName + "]" + mPendingBroadcast.curApp
    583                             + " died before responding to broadcast");
    584                     mPendingBroadcast.state = BroadcastRecord.IDLE;
    585                     mPendingBroadcast.nextReceiver = mPendingBroadcastRecvIndex;
    586                     mPendingBroadcast = null;
    587                 }
    588             }
    589 
    590             boolean looped = false;
    591             
    592             do {
    593                 if (mOrderedBroadcasts.size() == 0) {
    594                     // No more broadcasts pending, so all done!
    595                     mService.scheduleAppGcsLocked();
    596                     if (looped) {
    597                         // If we had finished the last ordered broadcast, then
    598                         // make sure all processes have correct oom and sched
    599                         // adjustments.
    600                         mService.updateOomAdjLocked();
    601                     }
    602                     return;
    603                 }
    604                 r = mOrderedBroadcasts.get(0);
    605                 boolean forceReceive = false;
    606 
    607                 // Ensure that even if something goes awry with the timeout
    608                 // detection, we catch "hung" broadcasts here, discard them,
    609                 // and continue to make progress.
    610                 //
    611                 // This is only done if the system is ready so that PRE_BOOT_COMPLETED
    612                 // receivers don't get executed with timeouts. They're intended for
    613                 // one time heavy lifting after system upgrades and can take
    614                 // significant amounts of time.
    615                 int numReceivers = (r.receivers != null) ? r.receivers.size() : 0;
    616                 if (mService.mProcessesReady &amp;&amp; r.dispatchTime &gt; 0) {
    617                     long now = SystemClock.uptimeMillis();
    618                     if ((numReceivers &gt; 0) &amp;&amp;
    619                             (now &gt; r.dispatchTime + (2*mTimeoutPeriod*numReceivers))) {
    620                         Slog.w(TAG, "Hung broadcast ["
    621                                 + mQueueName + "] discarded after timeout failure:"
    622                                 + " now=" + now
    623                                 + " dispatchTime=" + r.dispatchTime
    624                                 + " startTime=" + r.receiverTime
    625                                 + " intent=" + r.intent
    626                                 + " numReceivers=" + numReceivers
    627                                 + " nextReceiver=" + r.nextReceiver
    628                                 + " state=" + r.state);
    629                         broadcastTimeoutLocked(false); // forcibly finish this broadcast
    630                         forceReceive = true;
    631                         r.state = BroadcastRecord.IDLE;
    632                     }
    633                 }
    634 
    635                 if (r.state != BroadcastRecord.IDLE) {
    636                     if (DEBUG_BROADCAST) Slog.d(TAG,
    637                             "processNextBroadcast("
    638                             + mQueueName + ") called when not idle (state="
    639                             + r.state + ")");
    640                     return;
    641                 }
    642 
    643                 if (r.receivers == null || r.nextReceiver &gt;= numReceivers
    644                         || r.resultAbort || forceReceive) {
    645                     // No more receivers for this broadcast!  Send the final
    646                     // result if requested...
    647                     if (r.resultTo != null) {
    648                         try {
    649                             if (DEBUG_BROADCAST) {
    650                                 int seq = r.intent.getIntExtra("seq", -1);
    651                                 Slog.i(TAG, "Finishing broadcast ["
    652                                         + mQueueName + "] " + r.intent.getAction()
    653                                         + " seq=" + seq + " app=" + r.callerApp);
    654                             }
    655                             performReceiveLocked(r.callerApp, r.resultTo,
    656                                 new Intent(r.intent), r.resultCode,
    657                                 r.resultData, r.resultExtras, false, false, r.userId);
    658                             // Set this to null so that the reference
    659                             // (local and remote) isn't kept in the mBroadcastHistory.
    660                             r.resultTo = null;
    661                         } catch (RemoteException e) {
    662                             Slog.w(TAG, "Failure ["
    663                                     + mQueueName + "] sending broadcast result of "
    664                                     + r.intent, e);
    665                         }
    666                     }
    667 
    668                     if (DEBUG_BROADCAST) Slog.v(TAG, "Cancelling BROADCAST_TIMEOUT_MSG");
    669                     cancelBroadcastTimeoutLocked();
    670 
    671                     if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG, "Finished with ordered broadcast "
    672                             + r);
    673 
    674                     // ... and on to the next...
    675                     addBroadcastToHistoryLocked(r);
    676                     mOrderedBroadcasts.remove(0);
    677                     r = null;
    678                     looped = true;
    679                     continue;
    680                 }
    681             } while (r == null);
    682 
    683             // Get the next receiver...
    684             int recIdx = r.nextReceiver++;
    685 
    686             // Keep track of when this receiver started, and make sure there
    687             // is a timeout message pending to kill it if need be.
    688             r.receiverTime = SystemClock.uptimeMillis();
    689             if (recIdx == 0) {
    690                 r.dispatchTime = r.receiverTime;
    691                 r.dispatchClockTime = System.currentTimeMillis();
    692                 if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG, "Processing ordered broadcast ["
    693                         + mQueueName + "] " + r);
    694             }
    695             if (! mPendingBroadcastTimeoutMessage) {
    696                 long timeoutTime = r.receiverTime + mTimeoutPeriod;
    697                 if (DEBUG_BROADCAST) Slog.v(TAG,
    698                         "Submitting BROADCAST_TIMEOUT_MSG ["
    699                         + mQueueName + "] for " + r + " at " + timeoutTime);
    700                 setBroadcastTimeoutLocked(timeoutTime);
    701             }
    702 
    703             Object nextReceiver = r.receivers.get(recIdx);
    704             if (nextReceiver instanceof BroadcastFilter) {
    705                 // Simple case: this is a registered receiver who gets
    706                 // a direct call.
    707                 BroadcastFilter filter = (BroadcastFilter)nextReceiver;
    708                 if (DEBUG_BROADCAST)  Slog.v(TAG,
    709                         "Delivering ordered ["
    710                         + mQueueName + "] to registered "
    711                         + filter + ": " + r);
    712                 deliverToRegisteredReceiverLocked(r, filter, r.ordered);
    713                 if (r.receiver == null || !r.ordered) {
    714                     // The receiver has already finished, so schedule to
    715                     // process the next one.
    716                     if (DEBUG_BROADCAST) Slog.v(TAG, "Quick finishing ["
    717                             + mQueueName + "]: ordered="
    718                             + r.ordered + " receiver=" + r.receiver);
    719                     r.state = BroadcastRecord.IDLE;
    720                     scheduleBroadcastsLocked();
    721                 }
    722                 return;
    723             }
    724 
    725             // Hard case: need to instantiate the receiver, possibly
    726             // starting its application process to host it.
    727 
    728             ResolveInfo info =
    729                 (ResolveInfo)nextReceiver;
    730             ComponentName component = new ComponentName(
    731                     info.activityInfo.applicationInfo.packageName,
    732                     info.activityInfo.name);
    733 
    734             boolean skip = false;
    735             int perm = mService.checkComponentPermission(info.activityInfo.permission,
    736                     r.callingPid, r.callingUid, info.activityInfo.applicationInfo.uid,
    737                     info.activityInfo.exported);
    738             if (perm != PackageManager.PERMISSION_GRANTED) {
    739                 if (!info.activityInfo.exported) {
    740                     Slog.w(TAG, "Permission Denial: broadcasting "
    741                             + r.intent.toString()
    742                             + " from " + r.callerPackage + " (pid=" + r.callingPid
    743                             + ", uid=" + r.callingUid + ")"
    744                             + " is not exported from uid " + info.activityInfo.applicationInfo.uid
    745                             + " due to receiver " + component.flattenToShortString());
    746                 } else {
    747                     Slog.w(TAG, "Permission Denial: broadcasting "
    748                             + r.intent.toString()
    749                             + " from " + r.callerPackage + " (pid=" + r.callingPid
    750                             + ", uid=" + r.callingUid + ")"
    751                             + " requires " + info.activityInfo.permission
    752                             + " due to receiver " + component.flattenToShortString());
    753                 }
    754                 skip = true;
    755             }
    756             if (info.activityInfo.applicationInfo.uid != Process.SYSTEM_UID &amp;&amp;
    757                 r.requiredPermission != null) {
    758                 try {
    759                     perm = AppGlobals.getPackageManager().
    760                             checkPermission(r.requiredPermission,
    761                                     info.activityInfo.applicationInfo.packageName);
    762                 } catch (RemoteException e) {
    763                     perm = PackageManager.PERMISSION_DENIED;
    764                 }
    765                 if (perm != PackageManager.PERMISSION_GRANTED) {
    766                     Slog.w(TAG, "Permission Denial: receiving "
    767                             + r.intent + " to "
    768                             + component.flattenToShortString()
    769                             + " requires " + r.requiredPermission
    770                             + " due to sender " + r.callerPackage
    771                             + " (uid " + r.callingUid + ")");
    772                     skip = true;
    773                 }
    774             }
    775             if (r.appOp != AppOpsManager.OP_NONE) {
    776                 int mode = mService.mAppOpsService.noteOperation(r.appOp,
    777                         info.activityInfo.applicationInfo.uid, info.activityInfo.packageName);
    778                 if (mode != AppOpsManager.MODE_ALLOWED) {
    779                     if (DEBUG_BROADCAST)  Slog.v(TAG,
    780                             "App op " + r.appOp + " not allowed for broadcast to uid "
    781                             + info.activityInfo.applicationInfo.uid + " pkg "
    782                             + info.activityInfo.packageName);
    783                     skip = true;
    784                 }
    785             }
    786             if (!skip) {
    787                 skip = !mService.mIntentFirewall.checkBroadcast(r.intent, r.callingUid,
    788                         r.callingPid, r.resolvedType, info.activityInfo.applicationInfo.uid);
    789             }
    790             boolean isSingleton = false;
    791             try {
    792                 isSingleton = mService.isSingleton(info.activityInfo.processName,
    793                         info.activityInfo.applicationInfo,
    794                         info.activityInfo.name, info.activityInfo.flags);
    795             } catch (SecurityException e) {
    796                 Slog.w(TAG, e.getMessage());
    797                 skip = true;
    798             }
    799             if ((info.activityInfo.flags&amp;ActivityInfo.FLAG_SINGLE_USER) != 0) {
    800                 if (ActivityManager.checkUidPermission(
    801                         android.Manifest.permission.INTERACT_ACROSS_USERS,
    802                         info.activityInfo.applicationInfo.uid)
    803                                 != PackageManager.PERMISSION_GRANTED) {
    804                     Slog.w(TAG, "Permission Denial: Receiver " + component.flattenToShortString()
    805                             + " requests FLAG_SINGLE_USER, but app does not hold "
    806                             + android.Manifest.permission.INTERACT_ACROSS_USERS);
    807                     skip = true;
    808                 }
    809             }
    810             if (r.curApp != null &amp;&amp; r.curApp.crashing) {
    811                 // If the target process is crashing, just skip it.
    812                 Slog.w(TAG, "Skipping deliver ordered [" + mQueueName + "] " + r
    813                         + " to " + r.curApp + ": process crashing");
    814                 skip = true;
    815             }
    816 
    817             if (skip) {
    818                 if (DEBUG_BROADCAST)  Slog.v(TAG,
    819                         "Skipping delivery of ordered ["
    820                         + mQueueName + "] " + r + " for whatever reason");
    821                 r.receiver = null;
    822                 r.curFilter = null;
    823                 r.state = BroadcastRecord.IDLE;
    824                 scheduleBroadcastsLocked();
    825                 return;
    826             }
    827 
    828             r.state = BroadcastRecord.APP_RECEIVE;
    829             String targetProcess = info.activityInfo.processName;
    830             r.curComponent = component;
    831             if (r.callingUid != Process.SYSTEM_UID &amp;&amp; isSingleton) {
    832                 info.activityInfo = mService.getActivityInfoForUser(info.activityInfo, 0);
    833             }
    834             r.curReceiver = info.activityInfo;
    835             if (DEBUG_MU &amp;&amp; r.callingUid &gt; UserHandle.PER_USER_RANGE) {
    836                 Slog.v(TAG_MU, "Updated broadcast record activity info for secondary user, "
    837                         + info.activityInfo + ", callingUid = " + r.callingUid + ", uid = "
    838                         + info.activityInfo.applicationInfo.uid);
    839             }
    840 
    841             // Broadcast is being executed, its package can't be stopped.
    842             try {
    843                 AppGlobals.getPackageManager().setPackageStoppedState(
    844                         r.curComponent.getPackageName(), false, UserHandle.getUserId(r.callingUid));
    845             } catch (RemoteException e) {
    846             } catch (IllegalArgumentException e) {
    847                 Slog.w(TAG, "Failed trying to unstop package "
    848                         + r.curComponent.getPackageName() + ": " + e);
    849             }
    850 
    851             // Is this receiver's application already running?
    852             ProcessRecord app = mService.getProcessRecordLocked(targetProcess,
    853                     info.activityInfo.applicationInfo.uid, false);
    854             if (app != null &amp;&amp; app.thread != null) {
    855                 try {
    856                     app.addPackage(info.activityInfo.packageName, mService.mProcessStats);
    857                     processCurBroadcastLocked(r, app);
    858                     return;
    859                 } catch (RemoteException e) {
    860                     Slog.w(TAG, "Exception when sending broadcast to "
    861                           + r.curComponent, e);
    862                 } catch (RuntimeException e) {
    863                     Log.wtf(TAG, "Failed sending broadcast to "
    864                             + r.curComponent + " with " + r.intent, e);
    865                     // If some unexpected exception happened, just skip
    866                     // this broadcast.  At this point we are not in the call
    867                     // from a client, so throwing an exception out from here
    868                     // will crash the entire system instead of just whoever
    869                     // sent the broadcast.
    870                     logBroadcastReceiverDiscardLocked(r);
    871                     finishReceiverLocked(r, r.resultCode, r.resultData,
    872                             r.resultExtras, r.resultAbort, false);
    873                     scheduleBroadcastsLocked();
    874                     // We need to reset the state if we failed to start the receiver.
    875                     r.state = BroadcastRecord.IDLE;
    876                     return;
    877                 }
    878 
    879                 // If a dead object exception was thrown -- fall through to
    880                 // restart the application.
    881             }
    882 
    883             // Not running -- get it started, to be executed when the app comes up.
    884             if (DEBUG_BROADCAST)  Slog.v(TAG,
    885                     "Need to start app ["
    886                     + mQueueName + "] " + targetProcess + " for broadcast " + r);
    887             if ((r.curApp=mService.startProcessLocked(targetProcess,
    888                     info.activityInfo.applicationInfo, true,
    889                     r.intent.getFlags() | Intent.FLAG_FROM_BACKGROUND,
    890                     "broadcast", r.curComponent,
    891                     (r.intent.getFlags()&amp;Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0, false, false))
    892                             == null) {
    893                 // Ah, this recipient is unavailable.  Finish it if necessary,
    894                 // and mark the broadcast record as ready for the next.
    895                 Slog.w(TAG, "Unable to launch app "
    896                         + info.activityInfo.applicationInfo.packageName + "/"
    897                         + info.activityInfo.applicationInfo.uid + " for broadcast "
    898                         + r.intent + ": process is bad");
    899                 logBroadcastReceiverDiscardLocked(r);
    900                 finishReceiverLocked(r, r.resultCode, r.resultData,
    901                         r.resultExtras, r.resultAbort, false);
    902                 scheduleBroadcastsLocked();
    903                 r.state = BroadcastRecord.IDLE;
    904                 return;
    905             }
    906 
    907             mPendingBroadcast = r;
    908             mPendingBroadcastRecvIndex = recIdx;
    909         }
    910     }

    到这里其实开始走两个分支,1,如果是动态注册的receiver,其实可以知道,运行进程是活的,接收对象是存在的,deliverToRegisteredReceiverLocked(r, (BroadcastFilter)target, false),2,如果是静态注册的receiver,运行进程不确定是否存活,接收对象不存在,如果进程未拉起,mService.startProcessLocked(),启动接收进程然后继续scheduleBroadcastsLocked()循环,下次进入processCurBroadcastLocked(r, app)。既如果目标进程未启动,这里是会拉起来的。如果进程已启动,则processCurBroadcastLocked(r, app)分发广播。

    第一个分支: 

    429     private final void deliverToRegisteredReceiverLocked(BroadcastRecord r,
    430             BroadcastFilter filter, boolean ordered) {
    431         boolean skip = false;
    432         if (filter.requiredPermission != null) {
    433             int perm = mService.checkComponentPermission(filter.requiredPermission,
    434                     r.callingPid, r.callingUid, -1, true);
    435             if (perm != PackageManager.PERMISSION_GRANTED) {
    436                 Slog.w(TAG, "Permission Denial: broadcasting "
    437                         + r.intent.toString()
    438                         + " from " + r.callerPackage + " (pid="
    439                         + r.callingPid + ", uid=" + r.callingUid + ")"
    440                         + " requires " + filter.requiredPermission
    441                         + " due to registered receiver " + filter);
    442                 skip = true;
    443             }
    444         }
    445         if (!skip &amp;&amp; r.requiredPermission != null) {
    446             int perm = mService.checkComponentPermission(r.requiredPermission,
    447                     filter.receiverList.pid, filter.receiverList.uid, -1, true);
    448             if (perm != PackageManager.PERMISSION_GRANTED) {
    449                 Slog.w(TAG, "Permission Denial: receiving "
    450                         + r.intent.toString()
    451                         + " to " + filter.receiverList.app
    452                         + " (pid=" + filter.receiverList.pid
    453                         + ", uid=" + filter.receiverList.uid + ")"
    454                         + " requires " + r.requiredPermission
    455                         + " due to sender " + r.callerPackage
    456                         + " (uid " + r.callingUid + ")");
    457                 skip = true;
    458             }
    459         }
    460         if (r.appOp != AppOpsManager.OP_NONE) {
    461             int mode = mService.mAppOpsService.noteOperation(r.appOp,
    462                     filter.receiverList.uid, filter.packageName);
    463             if (mode != AppOpsManager.MODE_ALLOWED) {
    464                 if (DEBUG_BROADCAST)  Slog.v(TAG,
    465                         "App op " + r.appOp + " not allowed for broadcast to uid "
    466                         + filter.receiverList.uid + " pkg " + filter.packageName);
    467                 skip = true;
    468             }
    469         }
    470         if (!skip) {
    471             skip = !mService.mIntentFirewall.checkBroadcast(r.intent, r.callingUid,
    472                     r.callingPid, r.resolvedType, filter.receiverList.uid);
    473         }
    474 
    475         if (filter.receiverList.app == null || filter.receiverList.app.crashing) {
    476             Slog.w(TAG, "Skipping deliver [" + mQueueName + "] " + r
    477                     + " to " + filter.receiverList + ": process crashing");
    478             skip = true;
    479         }
    480 
    481         if (!skip) {
    482             // If this is not being sent as an ordered broadcast, then we
    483             // don't want to touch the fields that keep track of the current
    484             // state of ordered broadcasts.
    485             if (ordered) {
    486                 r.receiver = filter.receiverList.receiver.asBinder();
    487                 r.curFilter = filter;
    488                 filter.receiverList.curBroadcast = r;
    489                 r.state = BroadcastRecord.CALL_IN_RECEIVE;
    490                 if (filter.receiverList.app != null) {
    491                     // Bump hosting application to no longer be in background
    492                     // scheduling class.  Note that we can't do that if there
    493                     // isn't an app...  but we can only be in that case for
    494                     // things that directly call the IActivityManager API, which
    495                     // are already core system stuff so don't matter for this.
    496                     r.curApp = filter.receiverList.app;
    497                     filter.receiverList.app.curReceiver = r;
    498                     mService.updateOomAdjLocked(r.curApp, true);
    499                 }
    500             }
    501             try {
    502                 if (DEBUG_BROADCAST_LIGHT) {
    503                     int seq = r.intent.getIntExtra("seq", -1);
    504                     Slog.i(TAG, "Delivering to " + filter
    505                             + " (seq=" + seq + "): " + r);
    506                 }
    507                 performReceiveLocked(filter.receiverList.app, filter.receiverList.receiver,
    508                     new Intent(r.intent), r.resultCode, r.resultData,
    509                     r.resultExtras, r.ordered, r.initialSticky, r.userId);
    510                 if (ordered) {
    511                     r.state = BroadcastRecord.CALL_DONE_RECEIVE;
    512                 }
    513             } catch (RemoteException e) {
    514                 Slog.w(TAG, "Failure sending broadcast " + r.intent, e);
    515                 if (ordered) {
    516                     r.receiver = null;
    517                     r.curFilter = null;
    518                     filter.receiverList.curBroadcast = null;
    519                     if (filter.receiverList.app != null) {
    520                         filter.receiverList.app.curReceiver = null;
    521                     }
    522                 }
    523             }
    524         }
    525     }
    
    414     private static void performReceiveLocked(ProcessRecord app, IIntentReceiver receiver,
    415             Intent intent, int resultCode, String data, Bundle extras,
    416             boolean ordered, boolean sticky, int sendingUser) throws RemoteException {
    417         // Send the intent to the receiver asynchronously using one-way binder calls.
    418         if (app != null &amp;&amp; app.thread != null) {
    419             // If we have an app thread, do the call through that so it is
    420             // correctly ordered with other one-way calls.
    421             app.thread.scheduleRegisteredReceiver(receiver, intent, resultCode,
    422                     data, extras, ordered, sticky, sendingUser, app.repProcState);
    423         } else {
    424             receiver.performReceive(intent, resultCode, data, extras, ordered,
    425                     sticky, sendingUser);
    426         }
    427     }

    接着切换到ActivityThread

    812         public void scheduleRegisteredReceiver(IIntentReceiver receiver, Intent intent,
    813                 int resultCode, String dataStr, Bundle extras, boolean ordered,
    814                 boolean sticky, int sendingUser, int processState) throws RemoteException {
    815             updateProcessState(processState, false);
    816             receiver.performReceive(intent, resultCode, dataStr, extras, ordered,
    817                     sticky, sendingUser);
    818         }

    接着切换到ReceiverDispatcher.IntentReceiver/ReceiverDispatcher

    666         final static class InnerReceiver extends IIntentReceiver.Stub {
    667             final WeakReference&lt;LoadedApk.ReceiverDispatcher&gt; mDispatcher;
    668             final LoadedApk.ReceiverDispatcher mStrongRef;
    669 
    670             InnerReceiver(LoadedApk.ReceiverDispatcher rd, boolean strong) {
    671                 mDispatcher = new WeakReference&lt;LoadedApk.ReceiverDispatcher&gt;(rd);
    672                 mStrongRef = strong ? rd : null;
    673             }
    674             public void performReceive(Intent intent, int resultCode, String data,
    675                     Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
    676                 LoadedApk.ReceiverDispatcher rd = mDispatcher.get();
    677                 if (ActivityThread.DEBUG_BROADCAST) {
    678                     int seq = intent.getIntExtra("seq", -1);
    679                     Slog.i(ActivityThread.TAG, "Receiving broadcast " + intent.getAction() + " seq=" + seq
    680                             + " to " + (rd != null ? rd.mReceiver : null));
    681                 }
    682                 if (rd != null) {
    683                     rd.performReceive(intent, resultCode, data, extras,
    684                             ordered, sticky, sendingUser);
    685                 } else {
    686                     // The activity manager dispatched a broadcast to a registered
    687                     // receiver in this process, but before it could be delivered the
    688                     // receiver was unregistered.  Acknowledge the broadcast on its
    689                     // behalf so that the system's broadcast sequence can continue.
    690                     if (ActivityThread.DEBUG_BROADCAST) Slog.i(ActivityThread.TAG,
    691                             "Finishing broadcast to unregistered receiver");
    692                     IActivityManager mgr = ActivityManagerNative.getDefault();
    693                     try {
    694                         if (extras != null) {
    695                             extras.setAllowFds(false);
    696                         }
    697                         mgr.finishReceiver(this, resultCode, data, extras, false);
    698                     } catch (RemoteException e) {
    699                         Slog.w(ActivityThread.TAG, "Couldn't finish broadcast to unregistered receiver");
    700                     }
    701                 }
    702             }
    703         }
    
    834         public void performReceive(Intent intent, int resultCode, String data,
    835                 Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
    836             if (ActivityThread.DEBUG_BROADCAST) {
    837                 int seq = intent.getIntExtra("seq", -1);
    838                 Slog.i(ActivityThread.TAG, "Enqueueing broadcast " + intent.getAction() + " seq=" + seq
    839                         + " to " + mReceiver);
    840             }
    841             Args args = new Args(intent, resultCode, data, extras, ordered,
    842                     sticky, sendingUser);
    843             if (!mActivityThread.post(args)) {
    844                 if (mRegistered &amp;&amp; ordered) {
    845                     IActivityManager mgr = ActivityManagerNative.getDefault();
    846                     if (ActivityThread.DEBUG_BROADCAST) Slog.i(ActivityThread.TAG,
    847                             "Finishing sync broadcast to " + mReceiver);
    848                     args.sendFinished(mgr);
    849                 }
    850             }
    851         }
    
    715         final class Args extends BroadcastReceiver.PendingResult implements Runnable {
    716             private Intent mCurIntent;
    717             private final boolean mOrdered;
    718 
    719             public Args(Intent intent, int resultCode, String resultData, Bundle resultExtras,
    720                     boolean ordered, boolean sticky, int sendingUser) {
    721                 super(resultCode, resultData, resultExtras,
    722                         mRegistered ? TYPE_REGISTERED : TYPE_UNREGISTERED,
    723                         ordered, sticky, mIIntentReceiver.asBinder(), sendingUser);
    724                 mCurIntent = intent;
    725                 mOrdered = ordered;
    726             }
    727             
    728             public void run() {
    729                 final BroadcastReceiver receiver = mReceiver;
    730                 final boolean ordered = mOrdered;
    731                 
    732                 if (ActivityThread.DEBUG_BROADCAST) {
    733                     int seq = mCurIntent.getIntExtra("seq", -1);
    734                     Slog.i(ActivityThread.TAG, "Dispatching broadcast " + mCurIntent.getAction()
    735                             + " seq=" + seq + " to " + mReceiver);
    736                     Slog.i(ActivityThread.TAG, "  mRegistered=" + mRegistered
    737                             + " mOrderedHint=" + ordered);
    738                 }
    739                 
    740                 final IActivityManager mgr = ActivityManagerNative.getDefault();
    741                 final Intent intent = mCurIntent;
    742                 mCurIntent = null;
    743                 
    744                 if (receiver == null || mForgotten) {
    745                     if (mRegistered &amp;&amp; ordered) {
    746                         if (ActivityThread.DEBUG_BROADCAST) Slog.i(ActivityThread.TAG,
    747                                 "Finishing null broadcast to " + mReceiver);
    748                         sendFinished(mgr);
    749                     }
    750                     return;
    751                 }
    752 
    753                 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "broadcastReceiveReg");
    754                 try {
    755                     ClassLoader cl =  mReceiver.getClass().getClassLoader();
    756                     intent.setExtrasClassLoader(cl);
    757                     setExtrasClassLoader(cl);
    758                     receiver.setPendingResult(this);
    759                     receiver.onReceive(mContext, intent);
    760                 } catch (Exception e) {
    761                     if (mRegistered &amp;&amp; ordered) {
    762                         if (ActivityThread.DEBUG_BROADCAST) Slog.i(ActivityThread.TAG,
    763                                 "Finishing failed broadcast to " + mReceiver);
    764                         sendFinished(mgr);
    765                     }
    766                     if (mInstrumentation == null ||
    767                             !mInstrumentation.onException(mReceiver, e)) {
    768                         Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
    769                         throw new RuntimeException(
    770                             "Error receiving broadcast " + intent
    771                             + " in " + mReceiver, e);
    772                     }
    773                 }
    774                 
    775                 if (receiver.getPendingResult() != null) {
    776                     finish();
    777                 }
    778                 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
    779             }
    780         }

    3、在这里使用传入的handler(如果注册的时候没有传入,默认是主线程)post到相应的线程run,最后执行onReceive。

    第二个分支:

    212     private final void processCurBroadcastLocked(BroadcastRecord r,
    213             ProcessRecord app) throws RemoteException {
    214         if (DEBUG_BROADCAST)  Slog.v(TAG,
    215                 "Process cur broadcast " + r + " for app " + app);
    216         if (app.thread == null) {
    217             throw new RemoteException();
    218         }
    219         r.receiver = app.thread.asBinder();
    220         r.curApp = app;
    221         app.curReceiver = r;
    222         app.forceProcessStateUpTo(ActivityManager.PROCESS_STATE_RECEIVER);
    223         mService.updateLruProcessLocked(app, true, false);
    224 
    225         // Tell the application to launch this receiver.
    226         r.intent.setComponent(r.curComponent);
    227 
    228         boolean started = false;
    229         try {
    230             if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG,
    231                     "Delivering to component " + r.curComponent
    232                     + ": " + r);
    233             mService.ensurePackageDexOpt(r.intent.getComponent().getPackageName());
    234             app.thread.scheduleReceiver(new Intent(r.intent), r.curReceiver,
    235                     mService.compatibilityInfoForPackageLocked(r.curReceiver.applicationInfo),
    236                     r.resultCode, r.resultData, r.resultExtras, r.ordered, r.userId,
    237                     app.repProcState);
    238             if (DEBUG_BROADCAST)  Slog.v(TAG,
    239                     "Process cur broadcast " + r + " DELIVERED for app " + app);
    240             started = true;
    241         } finally {
    242             if (!started) {
    243                 if (DEBUG_BROADCAST)  Slog.v(TAG,
    244                         "Process cur broadcast " + r + ": NOT STARTED!");
    245                 r.receiver = null;
    246                 r.curApp = null;
    247                 app.curReceiver = null;
    248             }
    249         }
    250     }

    切换binder进程

    653         public final void scheduleReceiver(Intent intent, ActivityInfo info,
    654                 CompatibilityInfo compatInfo, int resultCode, String data, Bundle extras,
    655                 boolean sync, int sendingUser, int processState) {
    656             updateProcessState(processState, false);
    657             ReceiverData r = new ReceiverData(intent, resultCode, data, extras,
    658                     sync, false, mAppThread.asBinder(), sendingUser);
    659             r.info = info;
    660             r.compatInfo = compatInfo;
    661             queueOrSendMessage(H.RECEIVER, r);
    662         }
      
    //android.app.ActivityThread.H
    2038    private void queueOrSendMessage(int what, Object obj) {
    2039        queueOrSendMessage(what, obj, 0, 0);
    2040    }
    
    1471                case RECEIVER:
    1472                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "broadcastReceiveComp");
    1473                    handleReceiver((ReceiverData)msg.obj);
    1474                    maybeSnapshot();
    1475                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
    1476                    break;
    
    
    2359    private void handleReceiver(ReceiverData data) {
    2360        // If we are getting ready to gc after going to the background, well
    2361        // we are back active so skip it.
    2362        unscheduleGcIdler();
    2363
    2364        String component = data.intent.getComponent().getClassName();
    2365
    2366        LoadedApk packageInfo = getPackageInfoNoCheck(
    2367                data.info.applicationInfo, data.compatInfo);
    2368
    2369        IActivityManager mgr = ActivityManagerNative.getDefault();
    2370
    2371        BroadcastReceiver receiver;
    2372        try {
    2373            java.lang.ClassLoader cl = packageInfo.getClassLoader();
    2374            data.intent.setExtrasClassLoader(cl);
    2375            data.setExtrasClassLoader(cl);
    2376            receiver = (BroadcastReceiver)cl.loadClass(component).newInstance();
    2377        } catch (Exception e) {
    2378            if (DEBUG_BROADCAST) Slog.i(TAG,
    2379                    "Finishing failed broadcast to " + data.intent.getComponent());
    2380            data.sendFinished(mgr);
    2381            throw new RuntimeException(
    2382                "Unable to instantiate receiver " + component
    2383                + ": " + e.toString(), e);
    2384        }
    2385
    2386        try {
    2387            Application app = packageInfo.makeApplication(false, mInstrumentation);
    2388
    2389            if (localLOGV) Slog.v(
    2390                TAG, "Performing receive of " + data.intent
    2391                + ": app=" + app
    2392                + ", appName=" + app.getPackageName()
    2393                + ", pkg=" + packageInfo.getPackageName()
    2394                + ", comp=" + data.intent.getComponent().toShortString()
    2395                + ", dir=" + packageInfo.getAppDir());
    2396
    2397            ContextImpl context = (ContextImpl)app.getBaseContext();
    2398            sCurrentBroadcastIntent.set(data.intent);
    2399            receiver.setPendingResult(data);
    2400            receiver.onReceive(context.getReceiverRestrictedContext(),
    2401                    data.intent);
    2402        } catch (Exception e) {
    2403            if (DEBUG_BROADCAST) Slog.i(TAG,
    2404                    "Finishing failed broadcast to " + data.intent.getComponent());
    2405            data.sendFinished(mgr);
    2406            if (!mInstrumentation.onException(receiver, e)) {
    2407                throw new RuntimeException(
    2408                    "Unable to start receiver " + component
    2409                    + ": " + e.toString(), e);
    2410            }
    2411        } finally {
    2412            sCurrentBroadcastIntent.set(null);
    2413        }
    2414
    2415        if (receiver.getPendingResult() != null) {
    2416            data.finish();
    2417        }
    2418    }

    4、出口是receiver.onReceive(),静态注册的ClassLoader.loadClass().newInstance()创建实例,在主线程回调,到这里基本就完成所有流程。

    补:

     
     
  • 相关阅读:
    责任链模式(Chain of Responsibility)
    模板模式(Template Method)
    组合模式(Composite Pattern)
    原型模式(Prototype Pattern)
    策略模式(Strategy Pattern)
    状态模式(State Pattern)
    增删改查
    安卓sql
    安卓第三次作业
    安卓第四周作业
  • 原文地址:https://www.cnblogs.com/chenlong-50954265/p/5671188.html
Copyright © 2020-2023  润新知