1、相关代码

\frameworks\base\core\java\android\app\ContextImpl.java

\frameworks\base\core\java\android\app\LoadedApk.java

\frameworks\base\services\core\java\com\android\server\am\ActivityManagerService.java

\frameworks\base\services\core\java\com\android\server\am\BroadcastQueue.java

\frameworks\base\core\java\android\app\BroadcastOptions.java

\frameworks\base\services\core\java\com\android\server\am\ReceiverList.java

\frameworks\base\services\core\java\com\android\server\IntentResolver.java

\frameworks\base\services\core\java\com\android\server\am\BroadcastFilter.java

2.1广播动态注册流程

android广播动态注册与发送流程分析_第1张图片

简要流程如上图,注册过程主要通过AMS调用,将注册的intentFilter添加到BroadcastFilter中的队列mFilters中,同时将IIntentReceiver对象添加到mRegisteredReceivers中。

public Intent registerReceiver(IApplicationThread caller, String callerPackage,        IIntentReceiver receiver, IntentFilter filter, String permission, int userId,        int flags) {    ArrayList stickyIntents = null;    //...... 对调用者,instantApp、flag等做检查    //......处理粘性广播,将粘性广播加到粘性广播队列中    synchronized (this) {       //从现有队列中查找本地的IIntentReceiver        ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());        if (rl == null) {            //如果当前没有,则新建,并且每个应用只能创建1000个receiver超过会报异常            rl = new ReceiverList(this, callerApp, callingPid, callingUid,                    userId, receiver);            //......            mRegisteredReceivers.put(receiver.asBinder(), rl);        } else if (rl.uid != callingUid) {            //跟已有uid不同报异常        } else if (rl.pid != callingPid) {           //跟已有pid不同报异常        } else if (rl.userId != userId) {            //跟已有userId不同报异常        }        BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,                permission, callingUid, userId, instantApp, visibleToInstantApps);        if (rl.containsFilter(filter)) {            //intentfilter已存在,不再重复添加        } else {            rl.add(bf);            //添加intentFilter到mReceiverResolver表中            mReceiverResolver.addFilter(bf);        }        if (allSticky != null) {            //发送粘性广播            for (int i = 0; i < stickyCount; i++) {                Intent intent = allSticky.get(i);                BroadcastQueue queue = broadcastQueueForIntent(intent);                BroadcastRecord r = new BroadcastRecord(queue, intent, null,                        null, -1, -1, false, null, null, OP_NONE, null, receivers,                        null, 0, null, null, false, true, true, -1);                queue.enqueueParallelBroadcastLocked(r);                queue.scheduleBroadcastsLocked();            }        }     //......    }}

注册过程主要涉及两个重要标量:

final HashMap mRegisteredReceivers = new HashMap<>();final IntentResolver mReceiverResolver        = new IntentResolver() {    //......};
final class ReceiverList extends ArrayList        implements IBinder.DeathRecipient {    final ActivityManagerService owner;    public final IIntentReceiver receiver;    public final ProcessRecord app;    public final int pid;    public final int uid;    public final int userId;    BroadcastRecord curBroadcast = null;    boolean linkedToDeath = false;
final class BroadcastFilter extends IntentFilter {    // Back-pointer to the list this filter is in.    final ReceiverList receiverList;    final String packageName;    final String requiredPermission;    final int owningUid;    final int owningUserId;    final boolean instantApp;    final boolean visibleToInstantApp;

 

ReceiverList类相当于我们代码中的具体receiver,BroadcastFilter则相当于我们在注册广播时候施使用的intentFilter,一个进程不能注册超过1000个receiver,每个receiver中可以有多个BroadcastFilte,每次注册时候,先查找该receiver是否已经存在于当前的mRegisteredReceivers列表中了,如果已经存在,则检查这次注册者的pid、uid、userId是否跟已经存在的receiver中的这三个值相同,不同则抛出异常。

然后根据现有的或者新生成的ReceiverList名称rl,生成BroadcastFilter,如果该rl中已经包含给intentFilter,表示该已经存在了相同的receiver,包含了相同的intentfilter,不用再重复注册了,如果不包含,则将新生成的BroadcastFilter加入到rl中,将新建的BroadcastFilter加入到mReceiverResolver中。

 

解除注册,最重要的就是从这两个表中移出对象:

void removeReceiverLocked(ReceiverList rl) {    mRegisteredReceivers.remove(rl.receiver.asBinder());    for (int i = rl.size() - 1; i >= 0; i--) {        mReceiverResolver.removeFilter(rl.get(i));    }}

2.2 广播发送流程

 android广播动态注册与发送流程分析_第2张图片

广播发送简略流程如上图所示,在进行了一些列的检查,包括参数,调用者,广播flag,特殊action,系统广播,等之后,从mReceiverResolver中检索出广播接收者,然后按照优先无序广播,之后发送有序广播的顺序,依次调用所有接收者的IIntentReceiver中的onReceive中。

两个广播发送序列,前台序列、后台序列

BroadcastQueue mFgBroadcastQueue;BroadcastQueue mBgBroadcastQueue;

 

public final int broadcastIntent(IApplicationThread caller,        Intent intent, String resolvedType, IIntentReceiver resultTo,        int resultCode, String resultData, Bundle resultExtras,        String[] requiredPermissions, int appOp, Bundle bOptions,        boolean serialized, boolean sticky, int userId) {    enforceNotIsolatedCaller("broadcastIntent");    synchronized(this) {        intent = verifyBroadcastLocked(intent);        final ProcessRecord callerApp = getRecordForAppLocked(caller);        final int callingPid = Binder.getCallingPid();        final int callingUid = Binder.getCallingUid();        final long origId = Binder.clearCallingIdentity();        int res = broadcastIntentLocked(callerApp,                callerApp != null ? callerApp.info.packageName : null,                intent, resolvedType, resultTo, resultCode, resultData, resultExtras,                requiredPermissions, appOp, bOptions, serialized, sticky,                callingPid, callingUid, userId);        Binder.restoreCallingIdentity(origId);        return res;    }}

 

final int broadcastIntentLocked(ProcessRecord callerApp,        String callerPackage, Intent intent, String resolvedType,        IIntentReceiver resultTo, int resultCode, String resultData,        Bundle resultExtras, String[] requiredPermissions, int appOp, Bundle bOptions,        boolean ordered, boolean sticky, int callingPid, int callingUid, int userId) {                    //......flag 相关处理        if (callerInstantApp) {            intent.setFlags(intent.getFlags() & ~Intent.FLAG_RECEIVER_VISIBLE_TO_INSTANT_APPS);        }         intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);        if (!mProcessesReady && (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {            intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);        }         //......保护广播检测,非系统应用发送保护广播会报错        isProtectedBroadcast = AppGlobals.getPackageManager().isProtectedBroadcast(action);         if (!isCallerSystem) {                if (isProtectedBroadcast) {                    String msg = "Permission Denial: not allowed to send broadcast "                    + action + " from pid="                    + callingPid + ", uid=" + callingUid;                Slog.w(TAG, msg);                throw new SecurityException(msg);            //......        }             //......处理特殊action,如:ACTION_UID_REMOVED,ACTION_PACKAGES_UNSUSPENDED,ACTION_PACKAGE_REPLACED等         //如果发送的是粘性广播if (sticky) {    //检查android.Manifest.permission.BROADCAST_STICKY权限,没有则抛出异常    if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,        callingPid, callingUid)        != PackageManager.PERMISSION_GRANTED) {        String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="            + callingPid + ", uid=" + callingUid            + " requires " + android.Manifest.permission.BROADCAST_STICKY;        Slog.w(TAG, msg);        throw new SecurityException(msg);    }    //强制粘性广播必须带权限发送,否则直接返回    if (requiredPermissions != null && requiredPermissions.length > 0) {        Slog.w(TAG, "Can't broadcast sticky intent " + intent                + " and enforce permissions " + Arrays.toString(requiredPermissions));        return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;    }    //强制粘性广播不允许指定接收组件,否则抛出异常    if (intent.getComponent() != null) {        throw new SecurityException(                "Sticky broadcasts can't target a specific component");    }    //检查发送用户组   //......    for (i = 0; i < stickiesCount; i++) {        if (intent.filterEquals(list.get(i))) {            // 该粘性广播已经存在,直接替换            list.set(i, new Intent(intent));            break;        }    }    if (i >= stickiesCount) {        //不存在,则添加到队列中        list.add(new Intent(intent));    }    }        //一下两个列表用于装载广播接收者    List receivers = null;    List registeredReceivers = null;    //......    //检索广播接收对象    registeredReceivers = mReceiverResolver.queryIntent(intent,        resolvedType, false /*defaultOnly*/, userId);    //优先发送无序广播 ,ordered为false表示无序       int NR = registeredReceivers != null ? registeredReceivers.size() : 0;    if (!ordered && NR > 0) {        final BroadcastQueue queue = broadcastQueueForIntent(intent);        BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,            callerPackage, callingPid, callingUid, callerInstantApp, resolvedType,            requiredPermissions, appOp, brOptions, registeredReceivers, resultTo,            resultCode, resultData, resultExtras, ordered, sticky, false, userId);    // ......    if (!replaced) {        //发送广播        queue.enqueueParallelBroadcastLocked(r);        queue.scheduleBroadcastsLocked();    }    registeredReceivers = null;    NR = 0;    }      //......发送有序广播    BroadcastQueue queue = broadcastQueueForIntent(intent);    BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,        callerPackage, callingPid, callingUid, callerInstantApp, resolvedType,        requiredPermissions, appOp, brOptions, receivers, resultTo, resultCode,        resultData, resultExtras, ordered, sticky, false, userId);    queue.enqueueOrderedBroadcastLocked(r);    queue.scheduleBroadcastsLocked();         } 

BroadcastQueue中两个列表,无序广播队列、有序广播队列。

final ArrayList mParallelBroadcasts = new ArrayList<>();final ArrayList mOrderedBroadcasts = new ArrayList<>();

如以上分析,分别将有序广播和无序广播加入到不同的两个队列中。

public void enqueueParallelBroadcastLocked(BroadcastRecord r) {    mParallelBroadcasts.add(r);    enqueueBroadcastHelper(r);}public void enqueueOrderedBroadcastLocked(BroadcastRecord r) {    mOrderedBroadcasts.add(r);    enqueueBroadcastHelper(r);}

发送消息进入广播发送流程

public void scheduleBroadcastsLocked() {    if (mBroadcastsScheduled) {        return;    }    mHandler.sendMessage(mHandler.obtainMessage(BROADCAST_INTENT_MSG, this));    mBroadcastsScheduled = true;}

广播在同步方法块中进行

final void processNextBroadcast(boolean fromMsg) {    synchronized (mService) {        processNextBroadcastLocked(fromMsg, false);    }}

processNextBroadcastLocked方法详细流程如下:

final void processNextBroadcastLocked(boolean fromMsg, boolean skipOomAdj) {    BroadcastRecord r;    if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "processNextBroadcast ["            + mQueueName + "]: "            + mParallelBroadcasts.size() + " parallel broadcasts, "            + mOrderedBroadcasts.size() + " ordered broadcasts");    mService.updateCpuStats();    if (fromMsg) {        mBroadcastsScheduled = false;    }    // 先将无序广播发送掉    while (mParallelBroadcasts.size() > 0) {        r = mParallelBroadcasts.remove(0);        r.dispatchTime = SystemClock.uptimeMillis();        r.dispatchClockTime = System.currentTimeMillis();       ......        final int N = r.receivers.size();       ......        for (int i=0; i 0) {            synchronized (mService.mPidsSelfLocked) {                ProcessRecord proc = mService.mPidsSelfLocked.get(                        mPendingBroadcast.curApp.pid);                isDead = proc == null || proc.crashing;            }        } else {            final ProcessRecord proc = mService.mProcessNames.get(                    mPendingBroadcast.curApp.processName, mPendingBroadcast.curApp.uid);            isDead = proc == null || !proc.pendingStart;        }        if (!isDead) {            //此处无法理为什么进程存在的时候要返回            return;        } else {        ......            mPendingBroadcast.state = BroadcastRecord.IDLE;            mPendingBroadcast.nextReceiver = mPendingBroadcastRecvIndex;            mPendingBroadcast = null;        }    }    boolean looped = false;    do {        ......        //从有序广播队列中获取接收队列        r = mOrderedBroadcasts.get(0);        int numReceivers = (r.receivers != null) ? r.receivers.size() : 0;        if (mService.mProcessesReady && r.dispatchTime > 0) {            long now = SystemClock.uptimeMillis();            //如果现在距离dispatch时候的时间超过了mTimeoutPeriod的两倍,则进入超时ANR异常            //mTimeoutPeriod定义:前天广播10秒,后台广播60秒            if ((numReceivers > 0) &&                    (now > r.dispatchTime + (2*mTimeoutPeriod*numReceivers))) {                broadcastTimeoutLocked(false);                 forceReceive = true;                r.state = BroadcastRecord.IDLE;            }        }        ......            return;        }        if (r.receivers == null || r.nextReceiver >= numReceivers                || r.resultAbort || forceReceive) {                        if (r.resultTo != null) {                try {                   //通知到接收者的onrecevier中                    performReceiveLocked(r.callerApp, r.resultTo,                        new Intent(r.intent), r.resultCode,                        r.resultData, r.resultExtras, false, false, r.userId);                                       r.resultTo = null;                } catch (RemoteException e) {                }            }           ......            mOrderedBroadcasts.remove(0);            r = null;            looped = true;            continue;        }    } while (r == null);    // 得到下一个 receiver...    int recIdx = r.nextReceiver++;    // Keep track of when this receiver started, and make sure there    // is a timeout message pending to kill it if need be.    r.receiverTime = SystemClock.uptimeMillis();    if (recIdx == 0) {        r.dispatchTime = r.receiverTime;        r.dispatchClockTime = System.currentTimeMillis();        ......    }    if (! mPendingBroadcastTimeoutMessage) {        long timeoutTime = r.receiverTime + mTimeoutPeriod;       //设置发送超时        setBroadcastTimeoutLocked(timeoutTime);    }    final BroadcastOptions brOptions = r.options;    final Object nextReceiver = r.receivers.get(recIdx);    if (nextReceiver instanceof BroadcastFilter) {        BroadcastFilter filter = (BroadcastFilter)nextReceiver;       //发送广播        deliverToRegisteredReceiverLocked(r, filter, r.ordered, recIdx);        if (r.receiver == null || !r.ordered) {            //进入递归调用启动发送广播            scheduleBroadcastsLocked();        } else {            if (brOptions != null && brOptions.getTemporaryAppWhitelistDuration() > 0) {                scheduleTempWhitelistLocked(filter.owningUid,                        brOptions.getTemporaryAppWhitelistDuration(), r);            }        }        return;    }    //难点:需要实例化接收者,可能需要启动他们的应用用来支持这个receiver    ResolveInfo info =        (ResolveInfo)nextReceiver;    ComponentName component = new ComponentName(            info.activityInfo.applicationInfo.packageName,            info.activityInfo.name);    boolean skip = false;    //brOptions非空,并且当前targetSdkVersion小于option设置的最小值或者大于最大值,skip就为true,直接跳过    if (brOptions != null &&            (info.activityInfo.applicationInfo.targetSdkVersion                    < brOptions.getMinManifestReceiverApiLevel() ||            info.activityInfo.applicationInfo.targetSdkVersion                    > brOptions.getMaxManifestReceiverApiLevel())) {        skip = true;    }    //得到授权信息,系统或者root进程直接返回granted    int perm = mService.checkComponentPermission(info.activityInfo.permission,            r.callingPid, r.callingUid, info.activityInfo.applicationInfo.uid,            info.activityInfo.exported);    if (!skip && perm != PackageManager.PERMISSION_GRANTED) {        //不跳过,但是权限不允许,则skip置为true        skip = true;    } else if (!skip && info.activityInfo.permission != null) {        final int opCode = AppOpsManager.permissionToOpCode(info.activityInfo.permission);        if (opCode != AppOpsManager.OP_NONE                && mService.mAppOpsService.noteOperation(opCode, r.callingUid,                        r.callerPackage) != AppOpsManager.MODE_ALLOWED) {           //......permission不为空,并且appops授权检查未通过            skip = true;        }    }    if (!skip && info.activityInfo.applicationInfo.uid != Process.SYSTEM_UID &&        r.requiredPermissions != null && r.requiredPermissions.length > 0) {        for (int i = 0; i < r.requiredPermissions.length; i++) {            String requiredPermission = r.requiredPermissions[i];            try {                perm = AppGlobals.getPackageManager().                        checkPermission(requiredPermission,                                info.activityInfo.applicationInfo.packageName,                                UserHandle                                        .getUserId(info.activityInfo.applicationInfo.uid));            } catch (RemoteException e) {                perm = PackageManager.PERMISSION_DENIED;            }            if (perm != PackageManager.PERMISSION_GRANTED) {                //uid不等于SYSTEM_UID,requiredPermissions不为空,并且PMS未授权                skip = true;                break;            }            int appOp = AppOpsManager.permissionToOpCode(requiredPermission);            if (appOp != AppOpsManager.OP_NONE && appOp != r.appOp                    && mService.mAppOpsService.noteOperation(appOp,                    info.activityInfo.applicationInfo.uid, info.activityInfo.packageName)                    != AppOpsManager.MODE_ALLOWED) {                //uid不等于SYSTEM_UID,requiredPermissions不为空,并且APPOPS未授权                skip = true;                break;            }        }    }    if (!skip && r.appOp != AppOpsManager.OP_NONE            && mService.mAppOpsService.noteOperation(r.appOp,            info.activityInfo.applicationInfo.uid, info.activityInfo.packageName)            != AppOpsManager.MODE_ALLOWED) {        //appOp非空,并且appops权限检查未授予        skip = true;    }    if (!skip) {        //检测该intent是否阻塞        skip = !mService.mIntentFirewall.checkBroadcast(r.intent, r.callingUid,                r.callingPid, r.resolvedType, info.activityInfo.applicationInfo.uid);    }    boolean isSingleton = false;    try {        isSingleton = mService.isSingleton(info.activityInfo.processName,                info.activityInfo.applicationInfo,                info.activityInfo.name, info.activityInfo.flags);    } catch (SecurityException e) {        Slog.w(TAG, e.getMessage());        skip = true;    }    if ((info.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {        if (ActivityManager.checkUidPermission(                android.Manifest.permission.INTERACT_ACROSS_USERS,                info.activityInfo.applicationInfo.uid)                        != PackageManager.PERMISSION_GRANTED) {           //设置了activityInfo.flags,FLAG_SINGLE_USER,但没有INTERACT_ACROSS_USERS权限            skip = true;        }    }    if (!skip && info.activityInfo.applicationInfo.isInstantApp()            && r.callingUid != info.activityInfo.applicationInfo.uid) {       //isInstantApp跳过        skip = true;    }    if (!skip && r.callerInstantApp            && (info.activityInfo.flags & ActivityInfo.FLAG_VISIBLE_TO_INSTANT_APP) == 0            && r.callingUid != info.activityInfo.applicationInfo.uid) {       //callerInstantApp,并且设置了FLAG_VISIBLE_TO_INSTANT_APP        skip = true;    }    if (r.curApp != null && r.curApp.crashing) {        // 进程正在报错,跳过        skip = true;    }    if (!skip) {        boolean isAvailable = false;        try {            isAvailable = AppGlobals.getPackageManager().isPackageAvailable(                    info.activityInfo.packageName,                    UserHandle.getUserId(info.activityInfo.applicationInfo.uid));        } catch (Exception e) {        }        if (!isAvailable) {           //应用当前不可用 ,依然跳过            skip = true;        }    }    //如果组件权限需要review才能运行,跳过该广播,如果应用在前台,则启动review界面传递该intent    if (mService.mPermissionReviewRequired && !skip) {        if (!requestStartTargetPermissionsReviewIfNeededLocked(r,                info.activityInfo.packageName, UserHandle.getUserId(                        info.activityInfo.applicationInfo.uid))) {            skip = true;        }    }    ......    String targetProcess = info.activityInfo.processName;    ProcessRecord app = mService.getProcessRecordLocked(targetProcess,            info.activityInfo.applicationInfo.uid, false);    if (!skip) {        final int allowed = mService.getAppStartModeLocked(                info.activityInfo.applicationInfo.uid, info.activityInfo.packageName,                info.activityInfo.applicationInfo.targetSdkVersion, -1, true, false, false);        if (allowed != ActivityManager.APP_START_MODE_NORMAL) {            if (allowed == ActivityManager.APP_START_MODE_DISABLED) {                //startMode是APP_START_MODE_DISABLED的时候跳过                skip = true;            } else if (((r.intent.getFlags()&Intent.FLAG_RECEIVER_EXCLUDE_BACKGROUND) != 0)                    || (r.intent.getComponent() == null                        && r.intent.getPackage() == null                        && ((r.intent.getFlags()                                & Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND) == 0)                        && !isSignaturePerm(r.requiredPermissions))) {                mService.addBackgroundCheckViolationLocked(r.intent.getAction(),                        component.getPackageName());                //设置了FLAG_RECEIVER_EXCLUDE_BACKGROUND 或者 (component为空,并且package为空,并且                //设置了FLAG_RECEIVER_INCLUDE_BACKGROUND 并且requiredPermissions都是签名权限) 则跳过,不允许                skip = true;            }        }    }    if (!skip && !Intent.ACTION_SHUTDOWN.equals(r.intent.getAction())            && !mService.mUserController            .isUserRunning(UserHandle.getUserId(info.activityInfo.applicationInfo.uid),                    0 /* flags */)) {        skip = true;        //用户已经停止运行,跳过    }    if (skip) {        if (DEBUG_BROADCAST)  Slog.v(TAG_BROADCAST,                "Skipping delivery of ordered [" + mQueueName + "] "                + r + " for whatever reason");        r.delivery[recIdx] = BroadcastRecord.DELIVERY_SKIPPED;        r.receiver = null;        r.curFilter = null;        r.state = BroadcastRecord.IDLE;        r.manifestSkipCount++;        //递归调用发送广播流程        scheduleBroadcastsLocked();        return;    }    r.manifestCount++;    r.delivery[recIdx] = BroadcastRecord.DELIVERY_DELIVERED;    r.state = BroadcastRecord.APP_RECEIVE;    r.curComponent = component;    r.curReceiver = info.activityInfo;    if (brOptions != null && brOptions.getTemporaryAppWhitelistDuration() > 0) {        scheduleTempWhitelistLocked(receiverUid,                brOptions.getTemporaryAppWhitelistDuration(), r);    }    // 广播正在执行,包无法停止.    try {        AppGlobals.getPackageManager().setPackageStoppedState(                r.curComponent.getPackageName(), false, UserHandle.getUserId(r.callingUid));    } catch (RemoteException e) {    } catch (IllegalArgumentException e) {    }    // 接收进程正在运行    if (app != null && app.thread != null && !app.killed) {        try {            app.addPackage(info.activityInfo.packageName,                    info.activityInfo.applicationInfo.versionCode, mService.mProcessStats);            //调用app.thread.scheduleReceiver后返回                    processCurBroadcastLocked(r, app, skipOomAdj);            return;        } catch (RemoteException e) {                   } catch (RuntimeException e) {            //如果发生了预料之外的异常,则跳过这次广播,重新开发下次广播发送,            //这里现在是在系统进程中            logBroadcastReceiverDiscardLocked(r);            finishReceiverLocked(r, r.resultCode, r.resultData,                    r.resultExtras, r.resultAbort, false);            scheduleBroadcastsLocked();            // We need to reset the state if we failed to start the receiver.            r.state = BroadcastRecord.IDLE;            return;        }    }    //未在运行,则调用startProcessLocked启动该进程,用来接收广播    if ((r.curApp=mService.startProcessLocked(targetProcess,            info.activityInfo.applicationInfo, true,            r.intent.getFlags() | Intent.FLAG_FROM_BACKGROUND,            "broadcast", r.curComponent,            (r.intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0, false, false))                    == null) {        //进程启动过程发生异常,结束本次广播,继续下个广播        logBroadcastReceiverDiscardLocked(r);        finishReceiverLocked(r, r.resultCode, r.resultData,                r.resultExtras, r.resultAbort, false);        scheduleBroadcastsLocked();        r.state = BroadcastRecord.IDLE;        return;    }    mPendingBroadcast = r;    mPendingBroadcastRecvIndex = recIdx;}

deliverToRegisteredReceiverLocked方法流程分析:

private void deliverToRegisteredReceiverLocked(BroadcastRecord r,        BroadcastFilter filter, boolean ordered, int index) {    boolean skip = false;    if (filter.requiredPermission != null) {        int perm = mService.checkComponentPermission(filter.requiredPermission,                r.callingPid, r.callingUid, -1, true);        if (perm != PackageManager.PERMISSION_GRANTED) {            // BroadcastFilter所带权限不允许,跳过            skip = true;        } else {            final int opCode = AppOpsManager.permissionToOpCode(filter.requiredPermission);            if (opCode != AppOpsManager.OP_NONE                    && mService.mAppOpsService.noteOperation(opCode, r.callingUid,                            r.callerPackage) != AppOpsManager.MODE_ALLOWED) {                // BroadcastFilter所带权限appops检测不允许,跳过                skip = true;            }        }    }    //检查BroadcastRecord的requiredPermission是否通过PMS和APPOPS授权,若未授权,则跳过    if (!skip && (filter.receiverList.app == null || filter.receiverList.app.killed            || filter.receiverList.app.crashing)) {        //crash 进程跳过        skip = true;    }    ......    if (!skip && !visibleToInstantApps && filter.instantApp            && filter.receiverList.uid != r.callingUid) {        //instantApp 跳过        skip = true;    }    if (!skip && !filter.visibleToInstantApp && r.callerInstantApp            && filter.receiverList.uid != r.callingUid) {                skip = true;    }    //跳过该广播发送    if (skip) {        r.delivery[index] = BroadcastRecord.DELIVERY_SKIPPED;        return;    }    ......    try {       // ......发送广播            performReceiveLocked(filter.receiverList.app, filter.receiverList.receiver,                    new Intent(r.intent), r.resultCode, r.resultData,                    r.resultExtras, r.ordered, r.initialSticky, r.userId);        ......    } catch (RemoteException e) {        ......    }}

 

void performReceiveLocked(ProcessRecord app, IIntentReceiver receiver,        Intent intent, int resultCode, String data, Bundle extras,        boolean ordered, boolean sticky, int sendingUser) throws RemoteException {    // Send the intent to the receiver asynchronously using one-way binder calls.    if (app != null) {        if (app.thread != null) {            //app 与 thread 不为空,则直接调用scheduleRegisteredReceiver,回调进广播线程            try {                app.thread.scheduleRegisteredReceiver(receiver, intent, resultCode,                        data, extras, ordered, sticky, sendingUser, app.repProcState);            } catch (RemoteException ex) {                // Failed to call into the process. It's either dying or wedged. Kill it gently.                synchronized (mService) {                    Slog.w(TAG, "Can't deliver broadcast to " + app.processName                            + " (pid " + app.pid + "). Crashing it.");                    app.scheduleCrash("can't deliver broadcast");                }                throw ex;            }        } else {            // Application has died. Receiver doesn't exist.            throw new RemoteException("app.thread must not be null");        }    } else {        receiver.performReceive(intent, resultCode, data, extras, ordered,                sticky, sendingUser);    }}

通过binder远程调用,回到ApplicationThread中,

private class ApplicationThread extends IApplicationThread.Stub {public void scheduleRegisteredReceiver(IIntentReceiver receiver, Intent intent,        int resultCode, String dataStr, Bundle extras, boolean ordered,        boolean sticky, int sendingUser, int processState) throws RemoteException {    updateProcessState(processState, false);    receiver.performReceive(intent, resultCode, dataStr, extras, ordered,            sticky, sendingUser);}}

LoadedApk中流程如下:

static final class ReceiverDispatcher {    final static class InnerReceiver extends IIntentReceiver.Stub {        final WeakReference mDispatcher;        final LoadedApk.ReceiverDispatcher mStrongRef;        InnerReceiver(LoadedApk.ReceiverDispatcher rd, boolean strong) {            mDispatcher = new WeakReference(rd);            mStrongRef = strong ? rd : null;        }        @Override        public void performReceive(Intent intent, int resultCode, String data,                Bundle extras, boolean ordered, boolean sticky, int sendingUser) {           ......            if (rd != null) {                rd.performReceive(intent, resultCode, data, extras,                        ordered, sticky, sendingUser);            ......            }        }    }
public void performReceive(Intent intent, int resultCode, String data,        Bundle extras, boolean ordered, boolean sticky, int sendingUser) {    final Args args = new Args(intent, resultCode, data, extras, ordered,            sticky, sendingUser);    if (intent == null) {        Log.wtf(TAG, "Null intent received");    } else {        if (ActivityThread.DEBUG_BROADCAST) {            int seq = intent.getIntExtra("seq", -1);            Slog.i(ActivityThread.TAG, "Enqueueing broadcast " + intent.getAction()                    + " seq=" + seq + " to " + mReceiver);        }    }    //将该runnable发送到activitythread线程中执行,所以广播的执行是在主线程中,超时会产生ANR    if (intent == null || !mActivityThread.post(args.getRunnable())) {        if (mRegistered && ordered) {            IActivityManager mgr = ActivityManager.getService();            if (ActivityThread.DEBUG_BROADCAST) Slog.i(ActivityThread.TAG,                    "Finishing sync broadcast to " + mReceiver);            args.sendFinished(mgr);        }    }}

 Args类中流程如下:

public final Runnable getRunnable() {    return () -> {        final BroadcastReceiver receiver = mReceiver;        final boolean ordered = mOrdered;        ......        try {            ClassLoader cl = mReceiver.getClass().getClassLoader();            intent.setExtrasClassLoader(cl);            intent.prepareToEnterProcess();            setExtrasClassLoader(cl);            receiver.setPendingResult(this);            //回调到onReceiver接口            receiver.onReceive(mContext, intent);        } catch (Exception e) {           ......        }        ......    };

至此,广播的动态注册,和动态发送流程简要分析结束。

 

更多相关文章

  1. Android Bluetooth初始化流程
  2. Android 动态加载(三) - 类的加载流程源码分析
  3. android关机充电流程、充电画面显示
  4. Android 5.1 open data flow 数据开启流程
  5. Android: Android Reboot流程
  6. Android 指纹启动流程
  7. Android系统启动流程(4) —— 解析Launcher启动过程
  8. Android hardware so加载流程
  9. Android 7.1.2(Android N) Android系统启动流程

随机推荐

  1. android中隐藏ListView滚动条
  2. 快速实现android手机端多人视频会议直播(
  3. 【原】Android多任务下载,使用Notificatio
  4. 运行时动态注销在AndroidManifest.xml声
  5. android adb root方法
  6. uni-app之APP和小程序微信授权方法
  7. 22、TTS技术
  8. Android(安卓)Toolbar 使用总结
  9. android网络传输的传送对象
  10. Android(安卓)ADB命令大全(通过ADB命令查