Android Broadcast广播机制分析

来源:互联网 发布:php提权 编辑:程序博客网 时间:2024/05/16 18:33

基于Android 6.0的源码剖析, 分析android广播的发送与接收流程。

一、概述

广播(Broadcast)机制用于进程/线程间通信,广播分为广播发送和广播接收两个过程,其中广播接收者BroadcastReceiver便是Android四大组件之一。

BroadcastReceiver分为两类:

  • 静态广播接收者:通过AndroidManifest.xml的 标签来申明的BroadcastReceiver。
  • 动态广播接收者:通过AMS.registerReceiver()方式注册的BroadcastReceiver,动态注册更为灵活,可在不需要时通过unregisterReceiver()取消注册。

从广播发送方式可分为三类:

  • 普通广播:通过Context.sendBroadcast()发送,可并行处理
  • 有序广播:通过Context.sendOrderedBroadcast()发送,串行处理
  • Sticky广播:通过Context.sendOrderedBroadcast()发送

二、注册广播

2.1 registerReceiver

广播注册,对于应用开发来说,往往是在Activity/Service中调用 registerReceiver()方法,而Activity/Service都间接继承于Context抽象类,真正干活是交给ContextImpl类。另外调用getOuterContext()可获取最外层的调用者Activity/Service。

[ContextImpl.java]

@Overridepublic Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter) {    return registerReceiver(receiver, filter, null, null);}@Overridepublic Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter,        String broadcastPermission, Handler scheduler) {    //【见小节2.2】    return registerReceiverInternal(receiver, getUserId(),            filter, broadcastPermission, scheduler, getOuterContext());}

当执行两参数的 registerReceiver方法,增加两个broadcastPermission=null和scheduler=null调用四参数的注册方法。其中broadcastPermission拥有广播的权限控制,scheduler用于指定接收到广播时onRecive执行线程,当scheduler=null则默认代表在主线程中执行,这也是最常见的用法。 再然后调用6参数的registerReceiverInternal

2.2 registerReceiverInternal

[ContextImpl.java]

private Intent registerReceiverInternal(BroadcastReceiver receiver, int userId,        IntentFilter filter, String broadcastPermission,        Handler scheduler, Context context) {    IIntentReceiver rd = null;    if (receiver != null) {        if (mPackageInfo != null && context != null) {            if (scheduler == null) {                //将主线程Handler赋予scheuler                scheduler = mMainThread.getHandler();            }            //获取IIntentReceiver对象【2.3】            rd = mPackageInfo.getReceiverDispatcher(                receiver, context, scheduler,                mMainThread.getInstrumentation(), true);        } else {            if (scheduler == null) {                scheduler = mMainThread.getHandler();            }            rd = new LoadedApk.ReceiverDispatcher(                  receiver, context, scheduler, null, true).getIIntentReceiver();        }    }    try {        //调用AMP.registerReceiver 【2.4】        return ActivityManagerNative.getDefault().registerReceiver(                mMainThread.getApplicationThread(), mBasePackageName,                rd, filter, broadcastPermission, userId);    } catch (RemoteException e) {        return null;    }}

ActivityManagerNative.getDefault()返回的是ActivityManagerProxy对象,简称AMP,该方法中参数有mMainThread.getApplicationThread()返回的是ApplicationThread,这是Binder的Bn端,用于system_server进程与该进程的通信。

2.3 LoadedApk.getReceiverDispatcher

[-> LoadedApk.java]

public IIntentReceiver getReceiverDispatcher(BroadcastReceiver r,        Context context, Handler handler,        Instrumentation instrumentation, boolean registered) {    synchronized (mReceivers) {        LoadedApk.ReceiverDispatcher rd = null;        ArrayMap<BroadcastReceiver, LoadedApk.ReceiverDispatcher> map = null;        //此处registered=true,则进入该分支        if (registered) {            map = mReceivers.get(context);            if (map != null) {                rd = map.get(r);            }        }                if (rd == null) {            //当广播分发者为空,则创建ReceiverDispatcher【2.3.1】            rd = new ReceiverDispatcher(r, context, handler,                    instrumentation, registered);            if (registered) {                if (map == null) {                    map = new ArrayMap<BroadcastReceiver, LoadedApk.ReceiverDispatcher>();                    mReceivers.put(context, map);                }                map.put(r, rd);            }        } else {            //验证广播分发者的context、handler是否一致            rd.validate(context, handler);        }        rd.mForgotten = false;        //获取IIntentReceiver对象        return rd.getIIntentReceiver();    }}

不妨令 以BroadcastReceiver(广播接收者)为key,LoadedApk.ReceiverDispatcher(分发者)为value的ArrayMap 记为A。此处 mReceivers是一个以 Context为key,以 A为value的ArrayMap。对于ReceiverDispatcher(广播分发者),当不存在时则创建一个。

2.3.1 创建ReceiverDispatcher

ReceiverDispatcher(BroadcastReceiver receiver, Context context,        Handler activityThread, Instrumentation instrumentation,        boolean registered) {    //创建InnerReceiver【2.3.2】    mIIntentReceiver = new InnerReceiver(this, !registered);    mReceiver = receiver;    mContext = context;    mActivityThread = activityThread;    mInstrumentation = instrumentation;    mRegistered = registered;    mLocation = new IntentReceiverLeaked(null);    mLocation.fillInStackTrace();}

2.3.2 创建InnerReceiver

final static class InnerReceiver extends IIntentReceiver.Stub {    final WeakReference<LoadedApk.ReceiverDispatcher> mDispatcher;    final LoadedApk.ReceiverDispatcher mStrongRef;    InnerReceiver(LoadedApk.ReceiverDispatcher rd, boolean strong) {        mDispatcher = new WeakReference<LoadedApk.ReceiverDispatcher>(rd);        mStrongRef = strong ? rd : null;    }    ...}

ReceiverDispatcher(广播分发者)有一个内部类 InnerReceiver,该类继承于 IIntentReceiver.Stub。显然,这是一个Binder服务端,广播分发者通过rd.getIIntentReceiver()可获取该Binder服务端对象InnerReceiver,用于Binder IPC通信。

2.4 AMP.registerReceiver

[-> ActivityManagerNative.java]

public Intent registerReceiver(IApplicationThread caller, String packageName,        IIntentReceiver receiver,        IntentFilter filter, String perm, int userId) throws RemoteException{    Parcel data = Parcel.obtain();    Parcel reply = Parcel.obtain();    data.writeInterfaceToken(IActivityManager.descriptor);    data.writeStrongBinder(caller != null ? caller.asBinder() : null);    data.writeString(packageName);    data.writeStrongBinder(receiver != null ? receiver.asBinder() : null);    filter.writeToParcel(data, 0);    data.writeString(perm);    data.writeInt(userId);    //CommandREGISTER_RECEIVER_TRANSACTION    mRemote.transact(REGISTER_RECEIVER_TRANSACTION, data, reply, 0);    reply.readException();    Intent intent = null;    int haveIntent = reply.readInt();    if (haveIntent != 0) {        intent = Intent.CREATOR.createFromParcel(reply);    }    reply.recycle();    data.recycle();    return intent;}

这里有两个Binder服务端对象 callerreceiver,AMP通过Binder驱动将这些信息发送给system_server进程中的AMS对象,接下来进入AMS.registerReceiver。

2.5 AMS.registerReceiver

[-> ActivityManagerService.java]

public Intent registerReceiver(IApplicationThread caller, String callerPackage,        IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {    //孤立进程不允许注册广播接收者    enforceNotIsolatedCaller("registerReceiver");    ArrayList<Intent> stickyIntents = null;    ProcessRecord callerApp = null;    int callingUid;    int callingPid;    synchronized(this) {        if (caller != null) {            //从mLruProcesses队列中查找调用者的ProcessRecord 【见2.5.1】            callerApp = getRecordForAppLocked(caller);            //查询不到目标进程,则抛出异常            if (callerApp == null) {                throw new SecurityException("");            }            //非系统进程且包名不等于“android”,同时调用者进程不包括该包名时抛异常            if (callerApp.info.uid != Process.SYSTEM_UID &&                    !callerApp.pkgList.containsKey(callerPackage) &&                    !"android".equals(callerPackage)) {                throw new SecurityException("");            }            callingUid = callerApp.info.uid;            callingPid = callerApp.pid;        } else {            callerPackage = null;            callingUid = Binder.getCallingUid();            callingPid = Binder.getCallingPid();        }        userId = handleIncomingUser(callingPid, callingUid, userId,                true, ALLOW_FULL_ONLY, "registerReceiver", callerPackage);        //获取IntentFilter中的actions        Iterator<String> actions = filter.actionsIterator();        if (actions == null) {            ArrayList<String> noAction = new ArrayList<String>(1);            noAction.add(null);            actions = noAction.iterator();        }        int[] userIds = { UserHandle.USER_ALL, UserHandle.getUserId(callingUid) };        while (actions.hasNext()) {            String action = actions.next();            for (int id : userIds) {                //从mStickyBroadcasts中查看用户的sticky Intent                ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(id);                if (stickies != null) {                    ArrayList<Intent> intents = stickies.get(action);                    if (intents != null) {                        if (stickyIntents == null) {                            stickyIntents = new ArrayList<Intent>();                        }                        //将sticky Intent加入到队列                        stickyIntents.addAll(intents);                    }                }            }        }    }    ArrayList<Intent> allSticky = null;    if (stickyIntents != null) {        final ContentResolver resolver = mContext.getContentResolver();        for (int i = 0, N = stickyIntents.size(); i < N; i++) {            Intent intent = stickyIntents.get(i);            //查询匹配的sticky广播 【见2.5.2】            if (filter.match(resolver, intent, true, TAG) >= 0) {                if (allSticky == null) {                    allSticky = new ArrayList<Intent>();                }                //匹配成功,则将给intent添加到allSticky队列                allSticky.add(intent);            }        }    }    //当IIntentReceiver为空,则直接返回第一个sticky Intent,    Intent sticky = allSticky != null ? allSticky.get(0) : null;    if (receiver == null) {        return sticky;    }    synchronized (this) {        if (callerApp != null && (callerApp.thread == null                || callerApp.thread.asBinder() != caller.asBinder())) {            //调用者已经死亡            return null;        }        ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());        if (rl == null) {            //对于没有注册的广播,则创建接收者队列            rl = new ReceiverList(this, callerApp, callingPid, callingUid,                    userId, receiver);            if (rl.app != null) {                rl.app.receivers.add(rl);            } else {                try {                    //注册死亡通知                    receiver.asBinder().linkToDeath(rl, 0);                } catch (RemoteException e) {                    return sticky;                }                rl.linkedToDeath = true;            }            //新创建的接收者队列,添加到已注册广播队列。            mRegisteredReceivers.put(receiver.asBinder(), rl);        }        ...        //创建BroadcastFilter对象,并添加到接收者队列        BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,                permission, callingUid, userId);        rl.add(bf);        //新创建的广播过滤者,添加到ReceiverResolver队列        mReceiverResolver.addFilter(bf);        //所有匹配该filter的sticky广播执行入队操作        //如果没有使用sendStickyBroadcast,则allSticky=null。        if (allSticky != null) {            ArrayList receivers = new ArrayList();            receivers.add(bf);            final int stickyCount = allSticky.size();            for (int i = 0; i < stickyCount; i++) {                Intent intent = allSticky.get(i);                //当intent为前台广播,则返回mFgBroadcastQueue                //当intent为后台广播,则返回mBgBroadcastQueue                BroadcastQueue queue = broadcastQueueForIntent(intent);                //创建BroadcastRecord                BroadcastRecord r = new BroadcastRecord(queue, intent, null,                        null, -1, -1, null, null, AppOpsManager.OP_NONE, null, receivers,                        null, 0, null, null, false, true, true, -1);                //该广播加入到并行广播队列                queue.enqueueParallelBroadcastLocked(r);                //调度广播,发送BROADCAST_INTENT_MSG消息,触发处理下一个广播。                queue.scheduleBroadcastsLocked();            }        }        return sticky;    }}

其中 mRegisteredReceivers记录着所有已注册的广播,以receiver IBinder为key, ReceiverList为value为HashMap。另外,这个过程涉及对象ReceiverListBroadcastFilterBroadcastRecord的创建。

在BroadcastQueue中有两个广播队列 mParallelBroadcasts, mOrderedBroadcasts,数据类型都为ArrayList :

  • mParallelBroadcasts:并行广播队列,可以立刻执行,而无需等待另一个广播运行完成,该队列只允许动态已注册的广播,从而避免发生同时拉起大量进程来执行广播,前台的和后台的广播分别位于独立的队列。
  • mOrderedBroadcasts:有序广播队列,同一时间只允许执行一个广播,该队列顶部的广播便是活动广播,其他广播必须等待该广播结束才能运行,也是独立区别前台的和后台的广播。

2.5.1 AMS.getRecordForAppLocked

final ProcessRecord getRecordForAppLocked(        IApplicationThread thread) {    if (thread == null) {        return null;    }    //从mLruProcesses队列中查看    int appIndex = getLRURecordIndexForAppLocked(thread);    return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;}

mLruProcesses数据类型为 ArrayList<ProcessRecord>,而ProcessRecord对象有一个IApplicationThread字段,根据该字段查找出满足条件的ProcessRecord对象。

2.5.2 IntentFilter.match

public final int match(ContentResolver resolver, Intent intent,        boolean resolve, String logTag) {    String type = resolve ? intent.resolveType(resolver) : intent.getType();    return match(intent.getAction(), type, intent.getScheme(),                 intent.getData(), intent.getCategories(), logTag);}public final int match(String action, String type, String scheme,        Uri data, Set<String> categories, String logTag) {    //不存在匹配的action    if (action != null && !matchAction(action)) {        return NO_MATCH_ACTION;     }    //不存在匹配的type或data    int dataMatch = matchData(type, scheme, data);    if (dataMatch < 0) {        return dataMatch;     }    //不存在匹配的category    String categoryMismatch = matchCategories(categories);    if (categoryMismatch != null) {        return NO_MATCH_CATEGORY;    }    return dataMatch;}

该方法用于匹配发起的Intent数据是否匹配成功,匹配项共有4项action, type, data, category,任何一项匹配不成功都会失败。

小结

注册广播的过程,主要功能:

  • 创建ReceiverList(接收者队列),并添加到AMS.mRegisteredReceivers(已注册广播队列);
  • 创建BroadcastFilter(广播过滤者),并添加到AMS.mReceiverResolver(接收者的解析人);
  • 当注册的是Sticky广播,则创建BroadcastRecord,并添加到BroadcastQueue的mParallelBroadcasts(并行广播队列),注册后调用AMS来尽快处理该广播。

三、 发送广播

发送广播,同样往往是在Activity/Service中调用 registerReceiver()方法,而Activity/Service都间接继承于Context抽象类,真正干活是交给ContextImpl类。

3.1 sendBroadcast

[ContextImpl.java]

@Overridepublic void sendBroadcast(Intent intent) {    warnIfCallingFromSystemProcess();    String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());    try {        intent.prepareToLeaveProcess();        // 调用AMP.broadcastIntent  【见3.2】        ActivityManagerNative.getDefault().broadcastIntent(                mMainThread.getApplicationThread(), intent, resolvedType, null,                Activity.RESULT_OK, null, null, null, AppOpsManager.OP_NONE, null, false, false,                getUserId());    } catch (RemoteException e) {        throw new RuntimeException("Failure from system", e);    }}

3.2 AMP.broadcastIntent

[-> ActivityManagerNative.java]

public int broadcastIntent(IApplicationThread caller,        Intent intent, String resolvedType, IIntentReceiver resultTo,        int resultCode, String resultData, Bundle map,        String[] requiredPermissions, int appOp, Bundle options, boolean serialized,        boolean sticky, int userId) throws RemoteException{    Parcel data = Parcel.obtain();    Parcel reply = Parcel.obtain();    data.writeInterfaceToken(IActivityManager.descriptor);    data.writeStrongBinder(caller != null ? caller.asBinder() : null);    intent.writeToParcel(data, 0);    data.writeString(resolvedType);    data.writeStrongBinder(resultTo != null ? resultTo.asBinder() : null);    data.writeInt(resultCode);    data.writeString(resultData);    data.writeBundle(map);    data.writeStringArray(requiredPermissions);    data.writeInt(appOp);    data.writeBundle(options);    data.writeInt(serialized ? 1 : 0);    data.writeInt(sticky ? 1 : 0);    data.writeInt(userId);    //CommandBROADCAST_INTENT_TRANSACTION    mRemote.transact(BROADCAST_INTENT_TRANSACTION, data, reply, 0);    reply.readException();    int res = reply.readInt();    reply.recycle();    data.recycle();    return res;}

3.3 AMS.broadcastIntent

[-> ActivityManagerService.java]

public final int broadcastIntent(IApplicationThread caller,        Intent intent, String resolvedType, IIntentReceiver resultTo,        int resultCode, String resultData, Bundle resultExtras,        String[] requiredPermissions, int appOp, Bundle options,        boolean serialized, boolean sticky, int userId) {    enforceNotIsolatedCaller("broadcastIntent");    synchronized(this) {        //验证广播intent是否有效        intent = verifyBroadcastLocked(intent);        //获取调用者进程记录对象        final ProcessRecord callerApp = getRecordForAppLocked(caller);        final int callingPid = Binder.getCallingPid();        final int callingUid = Binder.getCallingUid();        final long origId = Binder.clearCallingIdentity();        //【见小节3.4】        int res = broadcastIntentLocked(callerApp,                callerApp != null ? callerApp.info.packageName : null,                intent, resolvedType, resultTo, resultCode, resultData, resultExtras,                requiredPermissions, appOp, null, serialized, sticky,                callingPid, callingUid, userId);        Binder.restoreCallingIdentity(origId);        return res;    }}

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

类型serializedstickysendBroadcastfalsefalsesendOrderedBroadcasttruefalsesendStickyBroadcastfalsetrue

3.4 AMS.broadcastIntentLocked

private final int broadcastIntentLocked(ProcessRecord callerApp,        String callerPackage, Intent intent, String resolvedType,        IIntentReceiver resultTo, int resultCode, String resultData,        Bundle resultExtras, String[] requiredPermissions, int appOp, Bundle options,        boolean ordered, boolean sticky, int callingPid, int callingUid, int userId) {        //part 1: 设置flag    //part 2: 广播权限验证    //part 3: 处理系统相关广播    //part 4: 增加sticky广播    //part 5: 查询receivers和registeredReceivers    //part 6: 处理并行广播    //part 7: 合并registeredReceivers到receivers    //part 8: 处理串行广播    return ActivityManager.BROADCAST_SUCCESS;}

broadcastIntentLocked方法比较长,这里划分为8个部分来分别说明。

part 1: 设置广播flag

    intent = new Intent(intent);    //增加该flag,则广播不会发送给已停止的package    intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);    //当没有启动完成时,不允许启动新进程    if (!mProcessesReady && (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);    }    userId = handleIncomingUser(callingPid, callingUid, userId,            true, ALLOW_NON_FULL, "broadcast", callerPackage);    //检查发送广播时用户状态    if (userId != UserHandle.USER_ALL && !isUserRunningLocked(userId, false)) {        if ((callingUid != Process.SYSTEM_UID                || (intent.getFlags() & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0)                && !Intent.ACTION_SHUTDOWN.equals(intent.getAction())) {            return ActivityManager.BROADCAST_FAILED_USER_STOPPED;        }    }

这个过程最重要的工作是:

  • 添加flag= FLAG_EXCLUDE_STOPPED_PACKAGES,保证已停止app不会收到该广播;
  • 当系统还没有启动完成,则不允许启动新进程,,即只有动态注册receiver才能接受广播
  • 当非USER_ALL广播且当前用户并没有处于Running的情况下,除非是系统升级广播或者关机广播,否则直接返回。

BroadcastReceiver还有其他flag,位于Intent.java常量:

FLAG_RECEIVER_REGISTERED_ONLY //只允许已注册receiver接收广播FLAG_RECEIVER_REPLACE_PENDING //新广播会替代相同广播FLAG_RECEIVER_FOREGROUND //只允许前台receiver接收广播FLAG_RECEIVER_NO_ABORT //对于有序广播,先接收到的receiver无权抛弃广播FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT //Boot完成之前,只允许已注册receiver接收广播FLAG_RECEIVER_BOOT_UPGRADE //升级模式下,允许系统准备就绪前可以发送广播

part 2: 广播权限验证

    int callingAppId = UserHandle.getAppId(callingUid);    if (callingAppId == Process.SYSTEM_UID || callingAppId == Process.PHONE_UID        || callingAppId == Process.SHELL_UID || callingAppId == Process.BLUETOOTH_UID        || callingAppId == Process.NFC_UID || callingUid == 0) {        //直接通过    } else if (callerApp == null || !callerApp.persistent) {        try {            if (AppGlobals.getPackageManager().isProtectedBroadcast(                    intent.getAction())) {                //不允许发送给受保护的广播                throw new SecurityException(msg);            } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(intent.getAction())) {                //这个case是出于兼容性考虑,限制只允许发送给自己。                ...            }        } catch (RemoteException e) {            return ActivityManager.BROADCAST_SUCCESS;        }    }

主要功能:

  • 对于callingAppId为SYSTEM_UID,PHONE_UID,SHELL_UID,BLUETOOTH_UID,NFC_UID之一或者callingUid == 0时都畅通无阻;
  • 否则对于调用者进程为空并且不是persistent进程的情况下:
    • 当发送的是受保护广播 mProtectedBroadcasts(只允许系统使用),则抛出异常;
    • 当action为ACTION_APPWIDGET_CONFIGURE时,虽然不希望该应用发送这种广播,处于兼容性考虑,限制该广播只允许发送给自己,否则抛出异常。

part 3: 处理系统相关广播

    final String action = intent.getAction();    if (action != null) {        switch (action) {            case Intent.ACTION_UID_REMOVED:                mBatteryStatsService.removeUid(uid);                mAppOpsService.uidRemoved(uid);                break;            case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:                String list[] = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);                if (list != null && list.length > 0) {                    for (int i = 0; i < list.length; i++) {                        forceStopPackageLocked(list[i], -1, false, true, true,                                false, false, userId, "storage unmount");                    }                    mRecentTasks.cleanupLocked(UserHandle.USER_ALL);                    sendPackageBroadcastLocked(                        IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list,userId);                }                break;            case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE                mRecentTasks.cleanupLocked(UserHandle.USER_ALL);                break;            case Intent.ACTION_PACKAGE_REMOVED:            case Intent.ACTION_PACKAGE_CHANGED:                Uri data = intent.getData();                boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(action);                boolean fullUninstall = removed && !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);                final boolean killProcess = !intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false);                if (killProcess) {                    forceStopPackageLocked(ssp, UserHandle.getAppId(                            intent.getIntExtra(Intent.EXTRA_UID, -1)),                            false, true, true, false, fullUninstall, userId,                            removed ? "pkg removed" : "pkg changed");                }                if (removed) {                    sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REMOVED,new String[] {ssp}, userId);                    if (fullUninstall) {                        mAppOpsService.packageRemoved(intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);                        removeUriPermissionsForPackageLocked(ssp, userId, true);                        removeTasksByPackageNameLocked(ssp, userId);                        mBatteryStatsService.notePackageUninstalled(ssp);                    }                } else {                    cleanupDisabledPackageComponentsLocked(ssp, userId, killProcess,                            intent.getStringArrayExtra(Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST));                }                break;            case Intent.ACTION_PACKAGE_ADDED:                Uri data = intent.getData();                final boolean replacing =intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);                mCompatModePackages.handlePackageAddedLocked(ssp, replacing);                ApplicationInfo ai = AppGlobals.getPackageManager().getApplicationInfo(ssp, 0, 0);                break;            case Intent.ACTION_TIMEZONE_CHANGED:                mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);                break;            case Intent.ACTION_TIME_CHANGED:                final int is24Hour = intent.getBooleanExtra(Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1: 0;                mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));                BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();                synchronized (stats) {                    stats.noteCurrentTimeChangedLocked();                }                break;            case Intent.ACTION_CLEAR_DNS_CACHE:                 mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);                break;            case Proxy.PROXY_CHANGE_ACTION:                ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);                mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));                break;        }    }

这个过程代码较长,主要处于系统相关的广播,如下10个case:

    case Intent.ACTION_UID_REMOVED: //uid移除    case Intent.ACTION_PACKAGE_REMOVED: //package移除,    case Intent.ACTION_PACKAGE_CHANGED: //package改变    case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE: //外部设备不可用时,强制停止所有波及的应用并清空cache数据    case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE: //外部设备可用    case Intent.ACTION_PACKAGE_ADDED: //增加package,处于兼容考虑    case Intent.ACTION_TIMEZONE_CHANGED: //时区改变,通知所有运行中的进程    case Intent.ACTION_TIME_CHANGED: //时间改变,通知所有运行中的进程    case Intent.ACTION_CLEAR_DNS_CACHE: //dns缓存清空    case Proxy.PROXY_CHANGE_ACTION: //网络代理改变

part 4:增加sticky广播

    if (sticky) {        if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,                callingPid, callingUid)                != PackageManager.PERMISSION_GRANTED) {            throw new SecurityException("");        }        if (requiredPermissions != null && requiredPermissions.length > 0) {            return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;        }                if (intent.getComponent() != null) {           //当sticky广播发送给指定组件,则throw Exception        }        if (userId != UserHandle.USER_ALL) {           //当非USER_ALL广播跟USER_ALL广播出现冲突,则throw Exception        }        ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);        if (stickies == null) {            stickies = new ArrayMap<>();            mStickyBroadcasts.put(userId, stickies);        }        ArrayList<Intent> list = stickies.get(intent.getAction());        if (list == null) {            list = new ArrayList<>();            stickies.put(intent.getAction(), list);        }        final int stickiesCount = list.size();        int i;        for (i = 0; i < stickiesCount; i++) {            if (intent.filterEquals(list.get(i))) {                //替换已存在的sticky intent                list.set(i, new Intent(intent));                break;            }        }        //新的intent追加到list        if (i >= stickiesCount) {            list.add(new Intent(intent));        }    }

这个过程主要是将sticky广播增加到list,并放入mStickyBroadcasts里面。

part 5:查询receivers和registeredReceivers

    int[] users;    if (userId == UserHandle.USER_ALL) {        users = mStartedUserArray; //广播给所有已启动用户    } else {        users = new int[] {userId}; //广播给指定用户    }    List receivers = null;    List<BroadcastFilter> registeredReceivers = null;    //找出所有能接收该广播的receivers    if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {        //根据intent查找相应的receivers        receivers = collectReceiverComponents(intent, resolvedType, callingUid, users);    }    if (intent.getComponent() == null) {        if (userId == UserHandle.USER_ALL && callingUid == Process.SHELL_UID) {            UserManagerService ums = getUserManagerLocked();            for (int i = 0; i < users.length; i++) {                //shell用户是否开启允许debug功能                if (ums.hasUserRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) {                    continue;                }                // 查询动态注册的广播                List<BroadcastFilter> registeredReceiversForUser =                        mReceiverResolver.queryIntent(intent,                                resolvedType, false, users[i]);                if (registeredReceivers == null) {                    registeredReceivers = registeredReceiversForUser;                } else if (registeredReceiversForUser != null) {                    registeredReceivers.addAll(registeredReceiversForUser);                }            }        } else {            // 查询动态注册的广播            registeredReceivers = mReceiverResolver.queryIntent(intent,                    resolvedType, false, userId);        }    }
  • receivers:记录着匹配当前intent的所有静态注册广播接收者;
  • registeredReceivers:记录着匹配当前的所有动态注册的广播接收者。

其中, mReceiverResolver是AMS的成员变量,记录着已注册的广播接收者的resolver.

AMS.collectReceiverComponents:

private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,        int callingUid, int[] users) {    List<ResolveInfo> receivers = null;    for (int user : users) {        //调用PKMS.queryIntentReceivers,可获取AndroidManifest.xml声明的接收者信息        List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()                .queryIntentReceivers(intent, resolvedType, STOCK_PM_FLAGS, user);        if (receivers == null) {            receivers = newReceivers;        } else if (newReceivers != null) {            ...            //将所用户的receiver整合到receivers        }     }    return receivers;}

part 6:处理并行广播

    //用于标识是否需要用新intent替换旧的intent。    final boolean replacePending = (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;    //处理并行广播    int NR = registeredReceivers != null ? registeredReceivers.size() : 0;    if (!ordered && NR > 0) {        final BroadcastQueue queue = broadcastQueueForIntent(intent);        //创建BroadcastRecord对象        BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,                callerPackage, callingPid, callingUid, resolvedType, requiredPermissions,                appOp, brOptions, registeredReceivers, resultTo, resultCode, resultData,                resultExtras, ordered, sticky, false, userId);        final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);        if (!replaced) {            //将BroadcastRecord加入到并行广播队列            queue.enqueueParallelBroadcastLocked(r);            //处理广播【见小节4.1】            queue.scheduleBroadcastsLocked();        }        registeredReceivers = null;        NR = 0;    }

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

part 7:合并registeredReceivers到receivers

    int ir = 0;    if (receivers != null) {        //防止应用监听该广播,在安装时直接运行。        String skipPackages[] = null;        if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())                || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())                || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {            Uri data = intent.getData();            if (data != null) {                String pkgName = data.getSchemeSpecificPart();                if (pkgName != null) {                    skipPackages = new String[] { pkgName };                }            }        } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {            skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);        }        //将skipPackages相关的广播接收者从receivers列表中移除        if (skipPackages != null && (skipPackages.length > 0)) {            for (String skipPackage : skipPackages) {                if (skipPackage != null) {                    int NT = receivers.size();                    for (int it=0; it<NT; it++) {                        ResolveInfo curt = (ResolveInfo)receivers.get(it);                        if (curt.activityInfo.packageName.equals(skipPackage)) {                            receivers.remove(it);                            it--;                            NT--;                        }                    }                }            }        }        //前面part6有一个处理动态广播的过程,处理完后再执行将动态注册的registeredReceivers合并到receivers        int NT = receivers != null ? receivers.size() : 0;        int it = 0;        ResolveInfo curt = null;        BroadcastFilter curr = null;        while (it < NT && ir < NR) {            if (curt == null) {                curt = (ResolveInfo)receivers.get(it);            }            if (curr == null) {                curr = registeredReceivers.get(ir);            }            if (curr.getPriority() >= curt.priority) {                receivers.add(it, curr);                ir++;                curr = null;                it++;                NT++;            } else {                  it++;                curt = null;            }        }    }    while (ir < NR) {        if (receivers == null) {            receivers = new ArrayList();        }        receivers.add(registeredReceivers.get(ir));        ir++;    }

part 8: 处理串行广播

    if ((receivers != null && receivers.size() > 0)            || resultTo != null) {        BroadcastQueue queue = broadcastQueueForIntent(intent);        //创建BroadcastRecord        BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,                callerPackage, callingPid, callingUid, resolvedType,                requiredPermissions, appOp, brOptions, receivers, resultTo, resultCode,                resultData, resultExtras, ordered, sticky, false, userId);        boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);        if (!replaced) {            //将BroadcastRecord加入到有序广播队列            queue.enqueueOrderedBroadcastLocked(r);            //处理广播【见小节4.1】            queue.scheduleBroadcastsLocked();         }    }

广播队列中有一个成员变量 mOrderedBroadcasts,类型为ArrayList ,记录着所有的有序广播。

四、 处理广播

在发送广播过程中会执行 scheduleBroadcastsLocked方法来处理相关的广播

4.1 scheduleBroadcastsLocked

[-> BroadcastQueue.java]

public void scheduleBroadcastsLocked() {        // 正在处理BROADCAST_INTENT_MSG消息    if (mBroadcastsScheduled) {        return;    }    //发送BROADCAST_INTENT_MSG消息    mHandler.sendMessage(mHandler.obtainMessage(BROADCAST_INTENT_MSG, this));    mBroadcastsScheduled = true;}

在BroadcastQueue对象创建时,mHandler=new BroadcastHandler(handler.getLooper());那么此处交由mHandler的handleMessage来处理:

private final class BroadcastHandler extends Handler {    public BroadcastHandler(Looper looper) {        super(looper, null, true);    }    @Override    public void handleMessage(Message msg) {        switch (msg.what) {            case BROADCAST_INTENT_MSG: {                processNextBroadcast(true); //【见小节4.2】            } break;            ...    }}

4.2 processNextBroadcast

[-> BroadcastQueue.java]

final void processNextBroadcast(boolean fromMsg) {    synchronized(mService) {        //part 1: 处理并行广播        //part 2: 处理有序广播        //part 3: 获取下条有序广播        //part 4: 处理下条有序广播    }}

此处mService为AMS,整个流程还是比较长的,全程持有AMS锁,所以广播效率低的情况下,直接会严重影响这个手机的性能与流畅度,这里应该考虑细化同步锁的粒度。

part 1: 处理并行广播

BroadcastRecord r;           mService.updateCpuStats(); //更新CPU统计信息if (fromMsg)  mBroadcastsScheduled = false;while (mParallelBroadcasts.size() > 0) {    r = mParallelBroadcasts.remove(0);    r.dispatchTime = SystemClock.uptimeMillis();    r.dispatchClockTime = System.currentTimeMillis();    final int N = r.receivers.size();    for (int i=0; i<N; i++) {        Object target = r.receivers.get(i);        //分发广播给已注册的receiver 【见小节4.3】        deliverToRegisteredReceiverLocked(r, (BroadcastFilter)target, false);    }    addBroadcastToHistoryLocked(r);//将广播添加历史统计}

part 2:处理有序广播

if (mPendingBroadcast != null) {    boolean isDead;    synchronized (mService.mPidsSelfLocked) {        //从mPidsSelfLocked获取正在处理该广播进程,判断该进程是否死亡        ProcessRecord proc = mService.mPidsSelfLocked.get(mPendingBroadcast.curApp.pid);        isDead = proc == null || proc.crashing;    }    if (!isDead) {        //正在处理广播的进程保持活跃状态,则继续等待其执行完成        return;    } else {        mPendingBroadcast.state = BroadcastRecord.IDLE;        mPendingBroadcast.nextReceiver = mPendingBroadcastRecvIndex;        mPendingBroadcast = null;    }}boolean looped = false;do {    if (mOrderedBroadcasts.size() == 0) {        //所有串行广播处理完成,则调度执行gc        mService.scheduleAppGcsLocked();        if (looped) {            mService.updateOomAdjLocked();        }        return;    }    r = mOrderedBroadcasts.get(0);    boolean forceReceive = false;    //获取所有该广播所有的接收者    int numReceivers = (r.receivers != null) ? r.receivers.size() : 0;    if (mService.mProcessesReady && r.dispatchTime > 0) {        long now = SystemClock.uptimeMillis();        if ((numReceivers > 0) &&                (now > r.dispatchTime + (2*mTimeoutPeriod*numReceivers))) {            //当广播处理时间超时,则强制结束这条广播            broadcastTimeoutLocked(false);            forceReceive = true;            r.state = BroadcastRecord.IDLE;        }    }    if (r.state != BroadcastRecord.IDLE) {        return;    }    if (r.receivers == null || r.nextReceiver >= numReceivers            || r.resultAbort || forceReceive) {        if (r.resultTo != null) {            //处理广播消息消息            performReceiveLocked(r.callerApp, r.resultTo,                new Intent(r.intent), r.resultCode,                r.resultData, r.resultExtras, false, false, r.userId);            r.resultTo = null;        }        //取消BROADCAST_TIMEOUT_MSG消息        cancelBroadcastTimeoutLocked();        addBroadcastToHistoryLocked(r);        mOrderedBroadcasts.remove(0);        r = null;        looped = true;        continue;    }} while (r == null);

mTimeoutPeriod,对于前台广播则为10s,对于后台广播则为60s,此时广播超时为 2*mTimeoutPeriod*numReceivers,接收者越多则广播超时总时长越长。

part 3: 获取下条有序广播

//获取下一个receiver的indexint recIdx = r.nextReceiver++;r.receiverTime = SystemClock.uptimeMillis();if (recIdx == 0) {    r.dispatchTime = r.receiverTime;    r.dispatchClockTime = System.currentTimeMillis();}if (!mPendingBroadcastTimeoutMessage) {    long timeoutTime = r.receiverTime + mTimeoutPeriod;    //设置广播超时时间,发送BROADCAST_TIMEOUT_MSG    setBroadcastTimeoutLocked(timeoutTime);}final BroadcastOptions brOptions = r.options;//获取下一个广播接收者final Object nextReceiver = r.receivers.get(recIdx);if (nextReceiver instanceof BroadcastFilter) {    //对于动态注册的广播接收者,deliverToRegisteredReceiverLocked处理广播    BroadcastFilter filter = (BroadcastFilter)nextReceiver;    deliverToRegisteredReceiverLocked(r, filter, r.ordered);    if (r.receiver == null || !r.ordered) {        r.state = BroadcastRecord.IDLE;        scheduleBroadcastsLocked();    } else {        ...    }    return;}//对于静态注册的广播接收者ResolveInfo info = (ResolveInfo)nextReceiver;ComponentName component = new ComponentName(        info.activityInfo.applicationInfo.packageName,        info.activityInfo.name);...//执行各种权限检测,此处省略,当权限不满足时skip=trueif (skip) {    r.receiver = null;    r.curFilter = null;    r.state = BroadcastRecord.IDLE;    scheduleBroadcastsLocked();    return;}r.state = BroadcastRecord.APP_RECEIVE;String targetProcess = info.activityInfo.processName;r.curComponent = component;final int receiverUid = info.activityInfo.applicationInfo.uid;if (r.callingUid != Process.SYSTEM_UID && isSingleton        && mService.isValidSingletonCall(r.callingUid, receiverUid)) {    info.activityInfo = mService.getActivityInfoForUser(info.activityInfo, 0);}r.curReceiver = info.activityInfo;...//Broadcast正在执行中,stopped状态设置成falseAppGlobals.getPackageManager().setPackageStoppedState(        r.curComponent.getPackageName(), false, UserHandle.getUserId(r.callingUid));

part 4: 处理下条有序广播

//该receiver所对应的进程已经运行,则直接处理ProcessRecord app = mService.getProcessRecordLocked(targetProcess,        info.activityInfo.applicationInfo.uid, false);if (app != null && app.thread != null) {    try {        app.addPackage(info.activityInfo.packageName,                info.activityInfo.applicationInfo.versionCode, mService.mProcessStats);        processCurBroadcastLocked(r, app);        return;    } catch (RemoteException e) {    } catch (RuntimeException e) {        finishReceiverLocked(r, r.resultCode, r.resultData, r.resultExtras, r.resultAbort, false);        scheduleBroadcastsLocked();        r.state = BroadcastRecord.IDLE; //启动receiver失败则重置状态        return;    }}//该receiver所对应的进程尚未启动,则创建该进程if ((r.curApp=mService.startProcessLocked(targetProcess,        info.activityInfo.applicationInfo, true,        r.intent.getFlags() | Intent.FLAG_FROM_BACKGROUND,        "broadcast", r.curComponent,        (r.intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0, false, false))                == null) {    //创建失败,则结束该receiver    finishReceiverLocked(r, r.resultCode, r.resultData,            r.resultExtras, r.resultAbort, false);    scheduleBroadcastsLocked();    r.state = BroadcastRecord.IDLE;    return;}mPendingBroadcast = r;mPendingBroadcastRecvIndex = recIdx;
  • 如果是动态广播接收者,则调用deliverToRegisteredReceiverLocked处理;
  • 如果是动态广播接收者,且对应进程已经创建,则调用processCurBroadcastLocked处理;
  • 如果是动态广播接收者,且对应进程尚未创建,则调用startProcessLocked创建进程。

4.3 deliverToRegisteredReceiverLocked

[-> BroadcastQueue.java]

private void deliverToRegisteredReceiverLocked(BroadcastRecord r,        BroadcastFilter filter, boolean ordered) {    ...    //检查发送者是否有BroadcastFilter所需权限    //以及接收者是否有发送者所需的权限等等    //当权限不满足要求,则skip=true。    if (!skip) {        //并行广播ordered = false,只有串行广播才进入该分支        if (ordered) {            r.receiver = filter.receiverList.receiver.asBinder();            r.curFilter = filter;            filter.receiverList.curBroadcast = r;            r.state = BroadcastRecord.CALL_IN_RECEIVE;            if (filter.receiverList.app != null) {                r.curApp = filter.receiverList.app;                filter.receiverList.app.curReceiver = r;                mService.updateOomAdjLocked(r.curApp);            }        }        // 处理广播【见小节4.4】        performReceiveLocked(filter.receiverList.app, filter.receiverList.receiver,                new Intent(r.intent), r.resultCode, r.resultData,                r.resultExtras, r.ordered, r.initialSticky, r.userId);        if (ordered) {            r.state = BroadcastRecord.CALL_DONE_RECEIVE;        }        ...    }}

4.4 deliverToRegisteredReceiverLocked

[-> BroadcastQueue.java]

private static void performReceiveLocked(ProcessRecord app, IIntentReceiver receiver,        Intent intent, int resultCode, String data, Bundle extras,        boolean ordered, boolean sticky, int sendingUser) throws RemoteException {    //通过binder异步机制,向receiver发送intent    if (app != null) {        if (app.thread != null) {            //调用ApplicationThreadProxy类对应的方法 【4.5】            app.thread.scheduleRegisteredReceiver(receiver, intent, resultCode,                    data, extras, ordered, sticky, sendingUser, app.repProcState);        } else {            //应用进程死亡,则Recevier并不存在            throw new RemoteException("app.thread must not be null");        }    } else {        //调用者进程为空,则执行该分支        receiver.performReceive(intent, resultCode, data, extras, ordered,                sticky, sendingUser);    }}

4.5 ATP.scheduleRegisteredReceiver

public void scheduleRegisteredReceiver(IIntentReceiver receiver, Intent intent,        int resultCode, String dataStr, Bundle extras, boolean ordered,        boolean sticky, int sendingUser, int processState) throws RemoteException {    Parcel data = Parcel.obtain();    data.writeInterfaceToken(IApplicationThread.descriptor);    data.writeStrongBinder(receiver.asBinder());    intent.writeToParcel(data, 0);    data.writeInt(resultCode);    data.writeString(dataStr);    data.writeBundle(extras);    data.writeInt(ordered ? 1 : 0);    data.writeInt(sticky ? 1 : 0);    data.writeInt(sendingUser);    data.writeInt(processState);    //command=SCHEDULE_REGISTERED_RECEIVER_TRANSACTION    mRemote.transact(SCHEDULE_REGISTERED_RECEIVER_TRANSACTION, data, null,            IBinder.FLAG_ONEWAY);    data.recycle();}

ATP位于system_server进程,是Binder Bp端通过Binder驱动向Binder Bn端发送消息, ATP所对应的Bn端位于发送广播调用端所在进程的ApplicationThread,即进入AT.scheduleRegisteredReceiver, 接下来说明该方法。

4.6 AT.scheduleRegisteredReceiver

[-> ActivityThread.java]

public void scheduleRegisteredReceiver(IIntentReceiver receiver, Intent intent,        int resultCode, String dataStr, Bundle extras, boolean ordered,        boolean sticky, int sendingUser, int processState) throws RemoteException {    //更新虚拟机进程状态    updateProcessState(processState, false);    //【见小节4.7】    receiver.performReceive(intent, resultCode, dataStr, extras, ordered,            sticky, sendingUser);}

此处receiver是注册广播时创建的,见小节[2.3],可知该 receiver= LoadedApk.ReceiverDispatcher.InnerReceiver

4.7 InnerReceiver.performReceive

[-> LoadedApk.java]

public void performReceive(Intent intent, int resultCode, String data,        Bundle extras, boolean ordered, boolean sticky, int sendingUser) {    LoadedApk.ReceiverDispatcher rd = mDispatcher.get();    if (rd != null) {        //【4.8】        rd.performReceive(intent, resultCode, data, extras, ordered, sticky, sendingUser);    } else {       ...    }}

4.8 ReceiverDispatcher.performReceive

[-> LoadedApk.java]

public void performReceive(Intent intent, int resultCode, String data,        Bundle extras, boolean ordered, boolean sticky, int sendingUser) {    Args args = new Args(intent, resultCode, data, extras, ordered,            sticky, sendingUser);    //通过handler消息机制发送args.    if (!mActivityThread.post(args)) {        if (mRegistered && ordered) {            IActivityManager mgr = ActivityManagerNative.getDefault();            args.sendFinished(mgr);        }    }}

其中 Args继承于 BroadcastReceiver.PendingResult,实现了接口 Runnable。这里mActivityThread.post(args) 消息机制,关于Handler消息机制,见 Android消息机制1-Handler(Java层),把消息放入MessageQueue,再调用Args的run()方法。

4.9 Args.run

[-> LoadedApk.java]

public final class LoadedApk {  static final class ReceiverDispatcher {    final class Args extends BroadcastReceiver.PendingResult implements Runnable {        public void run() {            final BroadcastReceiver receiver = mReceiver;            final boolean ordered = mOrdered;                       final IActivityManager mgr = ActivityManagerNative.getDefault();            final Intent intent = mCurIntent;            mCurIntent = null;                        if (receiver == null || mForgotten) {                if (mRegistered && ordered) {                    sendFinished(mgr);                }                return;            }            try {                //获取mReceiver的类加载器                ClassLoader cl =  mReceiver.getClass().getClassLoader();                intent.setExtrasClassLoader(cl);                setExtrasClassLoader(cl);                receiver.setPendingResult(this);                //回调广播onReceive方法                receiver.onReceive(mContext, intent);            } catch (Exception e) {                ...            }                        if (receiver.getPendingResult() != null) {                finish();            }        }      }    }

最终调用 BroadcastReceiver具体实现类的 onReceive()方法。

4.10 PendingResult.finish

[-> BroadcastReceiver.java]

public final void finish() {    final IActivityManager mgr = ActivityManagerNative.getDefault();    sendFinished(mgr);    ...}public void sendFinished(IActivityManager am) {    synchronized (this) {        try {            if (mResultExtras != null) {                mResultExtras.setAllowFds(false);            }            if (mOrderedHint) {                //串行广播                am.finishReceiver(mToken, mResultCode, mResultData, mResultExtras,                        mAbortBroadcast, mFlags);            } else {                //并行广播                am.finishReceiver(mToken, 0, null, null, false, mFlags);            }        } catch (RemoteException ex) {        }    }}

此处AMP.finishReceiver,经过binder调用,进入AMS.finishReceiver方法

4.11 AMS.finishReceiver

public void finishReceiver(IBinder who, int resultCode, String resultData,        Bundle resultExtras, boolean resultAbort, int flags) {     ...    final long origId = Binder.clearCallingIdentity();    try {        boolean doNext = false;        BroadcastRecord r;        synchronized(this) {            BroadcastQueue queue = (flags & Intent.FLAG_RECEIVER_FOREGROUND) != 0                    ? mFgBroadcastQueue : mBgBroadcastQueue;            r = queue.getMatchingOrderedReceiver(who);            if (r != null) {                doNext = r.queue.finishReceiverLocked(r, resultCode,                    resultData, resultExtras, resultAbort, true);            }        }        if (doNext) {            //处理下一条广播            r.queue.processNextBroadcast(false);        }        trimApplications();    } finally {        Binder.restoreCallingIdentity(origId);    }}

五、总结

未完留坑,后续总结以及增加流程图说明…

附录

本文所涉及的源码:

framework/base/core/java/android/content/BroadcastReceiver.javaframework/base/core/java/android/content/Context.javaframework/base/core/java/android/content/IntentFilter.javaframework/base/core/java/android/app/ContextImpl.javaframework/base/core/java/android/app/LoadedApkframework/base/core/java/android/app/ActivityManagerNative.javaframework/base/core/java/android/app/ApplicationThreadNative.javaframework/base/core/java/android/app/ActivityThread.javaframework/base/services/core/java/com/android/server/ActivityManagerService.javaframework/base/services/core/java/com/android/server/am/BroadcastQueue.javaframework/base/services/core/java/com/android/server/am/BroadcastFilter.javaframework/base/services/core/java/com/android/server/am/BroadcastRecord.javaframework/base/services/core/java/com/android/server/am/ReceiverList.java原文: http://gityuan.com/2016/06/04/broadcast-receiver/?utm_source=tuicool&utm_medium=referral 
0 0
原创粉丝点击