Android10.0 BroadcastReceiver工作原

2019-11-20  本文已影响0人  门心叼龙

本文出自门心叼龙的博客,属于原创类容,转载请注明出处。

BroadcastReceiver在Android四大组件中排行老三,它是一个广播接收器,用于系统中不同组件之间的通信,类似于事件编程中的事件监听器,只不过事件编程中监听的对象是控件,而广播接收器监听的对象是系统中的组件。广播分为普通广播,有序广播和粘性广播,本文主要研究普通广播的工作过程,包括广播接收器的注册、广播的发送、广播的接受背后的工作原理,其他两种类型都是类似的,大家可以触类旁通。

BroadcastReceiver的基本用法

首先需要定义一个广播接收器,如下所示:

public class MyReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        Log.v("MYTAG","onReceive start...");
    }
}

定义一个广播接收器的过程很简单,直接继承BroadcastReceiver这个抽象类,并实现它的抽象方法onReceive即可。广播接收器定义完毕,接下来的工作是注册广播,广播的注册分为动态注册和静态注册,大家注意了BroadcastReveiver是四大组件中唯一可以动态注册的组件,静态注册比较简单直接可以在清单文件AndroidMinifest.xml中通过receiver标签完成,我们主要看动态注册:

registerReceiver(new MyReceiver(),new IntentFilter("com.test.receiver"));

直接调用Context给我们提供的registerReceiver即可完成广播接收器的注册,该方法需要传入两个参数,第一个参数就是我们前面所定义的广播接收器MyReceiver对象,第二个参数是一个IntentFilter,它主要用来过滤广播的。广播接收器注册完成,最后一步就是发送广播了,代码实现如下:

sendBroadcast(new Intent("com.test.receiver"));

发送之后广播接收器MyReceiver就可以收到消息了,onReceive的方法响应了,打印日志如下:

2019-11-18 09:22:35.522 2721-2721/com.mxdl.customview V/MYTAG: onReceive start...

这样我们就轻轻轻松的体验了一把BroadcastReceiver的基本用法,接下来我们来看广播接收器的注册,广播发送,以及广播的接收他们背后的工作原理。

BroadcastReceiver的注册过程

ContextImpl中的流程

注册过程是从ContextWraper的registerReceiver方法开始的,如下所示:

 @Override
    public Intent registerReceiver(
        BroadcastReceiver receiver, IntentFilter filter) {
        return mBase.registerReceiver(receiver, filter);
    }

ContextWraper的registerReceiver方法很简单只有一行,ContextWraper什么都没有做,就把注册的工作交给了mBase,mBase在前面几篇文章我们多次提到过,在这里就不在重复讲解了,它就是ContextImpl,接下来,我们看ContextImpl的registerReceiver方法的实现:

 @Override
    public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter) {
        return registerReceiver(receiver, filter, null, null);
    }
    @Override
    public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter,
            String broadcastPermission, Handler scheduler) {
        return registerReceiverInternal(receiver, getUserId(),
                filter, broadcastPermission, scheduler, getOuterContext(), 0);
    }

registerReceiver方法回重载调用一次,然后再调用自己的registerReceiverInternal方法,该方法实现如下:

private Intent registerReceiverInternal(BroadcastReceiver receiver, int userId,
            IntentFilter filter, String broadcastPermission,
            Handler scheduler, Context context, int flags) {
        IIntentReceiver rd = null;
        if (receiver != null) {
            if (mPackageInfo != null && context != null) {
                if (scheduler == null) {
                    scheduler = mMainThread.getHandler();
                }
                rd = mPackageInfo.getReceiverDispatcher(
                    receiver, context, scheduler,
                    mMainThread.getInstrumentation(), true);
            } else {
                if (scheduler == null) {
                    scheduler = mMainThread.getHandler();
                }
                //注释1
                rd = new LoadedApk.ReceiverDispatcher(
                        receiver, context, scheduler, null, true).getIIntentReceiver();
            }
        }
        try {
            //注释2
            final Intent intent = ActivityManager.getService().registerReceiver(
                    mMainThread.getApplicationThread(), mBasePackageName, rd, filter,
                    broadcastPermission, userId, flags);
            if (intent != null) {
                intent.setExtrasClassLoader(getClassLoader());
                intent.prepareToEnterProcess();
            }
            return intent;
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
        }
    }

我们主要看注释1处,将传递过来的receiver转化为了IIntentReceiver,我们看ReceiverDispatcher的getIIntentReceiver方法返回的到底是什么,如下所示:

final IIntentReceiver.Stub mIIntentReceiver;
 @UnsupportedAppUsage
        IIntentReceiver getIIntentReceiver() {
            return mIIntentReceiver;
        }

一目了然,返回的是一个IIntentReceiver.Stub类型的变量mIIntentReceiver,我看mIIntentReceiver是在什么时候初始化的,经过变量跟踪我们可以知道,就是在ReceiverDispatcher对象实例化的时候就赋值了,代码实现如下:

ReceiverDispatcher(BroadcastReceiver receiver, Context context,
                Handler activityThread, Instrumentation instrumentation,
                boolean registered) {
            if (activityThread == null) {
                throw new NullPointerException("Handler must not be null");
            }
            //注释1
            mIIntentReceiver = new InnerReceiver(this, !registered);
            mReceiver = receiver;
            mContext = context;
            mActivityThread = activityThread;
            mInstrumentation = instrumentation;
            mRegistered = registered;
            mLocation = new IntentReceiverLeaked(null);
            mLocation.fillInStackTrace();
        }

在注释1处mIIntentReceiver变量被初始化了,它的具体实现就是InnerReceiver,它的继承关系如下:

final static class InnerReceiver extends IIntentReceiver.Stub

到了这一步我们也就明白了,客户端会将BroadcastReceiver对象转换为一个ReceiverDispatcher.InnerReceiver对象,之所以不能直接传递BroadcastReceiver对象是因为广播的发送有可能是跨进程的,BroadcastReceiver只能借助于Binder对象才能在服务端回调自己的方法,而ReceiverDispatcher的内部类InnerReceiver正好充当了Binder这个角色。ReceiverDispatcher同时持有BroadcastReceiver和InnerReceiver,
InnerReceiver反向持有ReceiverDispatcher。我们有没有发现,这和上一篇我们在学习Service绑定的时候是一个套路,ServiceConnetion对象也是被转化为ServiceDispatcher.InnerConnection对象传递的。

回过头我们再看ContextImple对象的registerReceiverInternal方法的注释2处调用了ActivityManager.getService()对象的registerReceiver方法此时把InnerReceiver对象传递给给服务端了,ActivityManager.getService()对象不用多想就是ActivityManagerService对象,现在我们看registerReceiver方法的实现,如下所示:

ActivityManagerService中的流程
public Intent registerReceiver(IApplicationThread caller, String callerPackage,
            IIntentReceiver receiver, IntentFilter filter, String permission, int userId,
            int flags) {
    ...
    if (rl == null) {
                rl = new ReceiverList(this, callerApp, callingPid, callingUid,
                        userId, receiver);
                if (rl.app != null) {
                    final int totalReceiversForApp = rl.app.receivers.size();
                    if (totalReceiversForApp >= MAX_RECEIVERS_ALLOWED_PER_APP) {
                        throw new IllegalStateException("Too many receivers, total of "
                                + totalReceiversForApp + ", registered for pid: "
                                + rl.pid + ", callerPackage: " + callerPackage);
                    }
                    rl.app.receivers.add(rl);
                } else {
                    try {
                        receiver.asBinder().linkToDeath(rl, 0);
                    } catch (RemoteException e) {
                        return sticky;
                    }
                    rl.linkedToDeath = true;
                }
                //注释1
                mRegisteredReceivers.put(receiver.asBinder(), rl);
            } else if (rl.uid != callingUid) {
                throw new IllegalArgumentException(
                        "Receiver requested to register for uid " + callingUid
                        + " was previously registered for uid " + rl.uid
                        + " callerPackage is " + callerPackage);
            } else if (rl.pid != callingPid) {
                throw new IllegalArgumentException(
                        "Receiver requested to register for pid " + callingPid
                        + " was previously registered for pid " + rl.pid
                        + " callerPackage is " + callerPackage);
            } else if (rl.userId != userId) {
                throw new IllegalArgumentException(
                        "Receiver requested to register for user " + userId
                        + " was previously registered for user " + rl.userId
                        + " callerPackage is " + callerPackage);
            }
            BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
                    permission, callingUid, userId, instantApp, visibleToInstantApps);
            if (rl.containsFilter(filter)) {
                Slog.w(TAG, "Receiver with filter " + filter
                        + " already registered for pid " + rl.pid
                        + ", callerPackage is " + callerPackage);
            } else {
                rl.add(bf);
                if (!bf.debugCheck()) {
                    Slog.w(TAG, "==> For Dynamic broadcast");
                }
                //注释2
                mReceiverResolver.addFilter(bf);
            }
            ...

服务端的registerReceiver是实现广播注册的真正方法,该方法很长我们只看重要的部分,在注释1处将客户端传递过来的广播接收器InnerReceiver保存起来,在最后的注释2处将客户端传递过来的IntentFilter也保存起来,这样整个广播注册过程就完成了。

广播的发送和接收

ContextImpl中的流程

接下来我们看广播的发送和接收过程,和广播注册一样,广播发送也是从ContextWraper的sendBroadcast方法开始的,方法如下:

 @Override
    public void sendBroadcast(Intent intent) {
        mBase.sendBroadcast(intent);
    }

该方法里面什么也没有做,直接就把发送的工作交给了ContextImple的sendBroadcast方法了,该方法实现如下:

 @Override
    public void sendBroadcast(Intent intent) {
        warnIfCallingFromSystemProcess();
        String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
        try {
            intent.prepareToLeaveProcess(this);
            //注释1
            ActivityManager.getService().broadcastIntent(
                    mMainThread.getApplicationThread(), intent, resolvedType, null,
                    Activity.RESULT_OK, null, null, null, AppOpsManager.OP_NONE, null, false, false,
                    getUserId());
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
        }
    }
ActivityManagerService中的流程

在注释1处调用了ActivityManagerService的broadcastIntent方法,具体的代码实现如下所示:

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();
            try {
                //注释1
                return broadcastIntentLocked(callerApp,
                        callerApp != null ? callerApp.info.packageName : null,
                        intent, resolvedType, resultTo, resultCode, resultData, resultExtras,
                        requiredPermissions, appOp, bOptions, serialized, sticky,
                        callingPid, callingUid, callingUid, callingPid, userId);
            } finally {
                Binder.restoreCallingIdentity(origId);
            }
        }
    }

ActivityManagerService的broadcastIntent方法也不长,在方法的最后会调用它的broadcastIntentLocked方法,该方法会被重载调用一次,broadcastIntentLocked方法的具体实现如下:

  @GuardedBy("this")
    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 realCallingUid,
            int realCallingPid, int userId, boolean allowBackgroundActivityStarts) {
 ...
 int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
        if (!ordered && NR > 0) {
            // If we are not serializing this broadcast, then send the
            // registered receivers separately so they don't wait for the
            // components to be launched.
            if (isCallerSystem) {
                checkBroadcastFromSystem(intent, callerApp, callerPackage, callingUid,
                        isProtectedBroadcast, registeredReceivers);
            }
            //注释1
            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,
                    allowBackgroundActivityStarts, timeoutExempt);
            if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing parallel broadcast " + r);
            final boolean replaced = replacePending
                    && (queue.replaceParallelBroadcastLocked(r) != null);
            // Note: We assume resultTo is null for non-ordered broadcasts.
            if (!replaced) {
                queue.enqueueParallelBroadcastLocked(r);
                //注释2
                queue.scheduleBroadcastsLocked();
            }
            registeredReceivers = null;
            NR = 0;
        }
        ...

这个方法的很长,但是他只做了一件事,通过传递过来的Intent查找相匹配的的BroadcastReceiver并把它放入到广播队列BroadcastQueue中,如注释1所示,接下来会调用注释2处的scheduleBroadcastsLocked方法执行广播发送任务,下面是BroadcastQueue的scheduleBroadcastsLocked方法的具体实现:

BroadcastQueue中的流程
public void scheduleBroadcastsLocked() {
        if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Schedule broadcasts ["
                + mQueueName + "]: current="
                + mBroadcastsScheduled);

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

该方法的逻辑实现也不是很长,就向消息管理器mHandler发送了一个BROADCAST_INTENT_MSG类型的消息,mHandler收到消息后回调它自己的processNextBroadcast方法,processNextBroadcast方法又会调用processNextBroadcastLocked方法,它的具体实现如下:

  final void processNextBroadcastLocked(boolean fromMsg, boolean skipOomAdj) {
        BroadcastRecord r;
        ...
        // First, deliver any non-serialized broadcasts right away.
        while (mParallelBroadcasts.size() > 0) {
            r = mParallelBroadcasts.remove(0);
            r.dispatchTime = SystemClock.uptimeMillis();
            r.dispatchClockTime = System.currentTimeMillis();

            if (Trace.isTagEnabled(Trace.TRACE_TAG_ACTIVITY_MANAGER)) {
                Trace.asyncTraceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER,
                    createBroadcastTraceTitle(r, BroadcastRecord.DELIVERY_PENDING),
                    System.identityHashCode(r));
                Trace.asyncTraceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER,
                    createBroadcastTraceTitle(r, BroadcastRecord.DELIVERY_DELIVERED),
                    System.identityHashCode(r));
            }

            final int N = r.receivers.size();
            if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG_BROADCAST, "Processing parallel broadcast ["
                    + mQueueName + "] " + r);
            for (int i=0; i<N; i++) {
                Object target = r.receivers.get(i);
                if (DEBUG_BROADCAST)  Slog.v(TAG_BROADCAST,
                        "Delivering non-ordered on [" + mQueueName + "] to registered "
                        + target + ": " + r);
                //注释1     
                deliverToRegisteredReceiverLocked(r, (BroadcastFilter)target, false, i);
            }
            addBroadcastToHistoryLocked(r);
            if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG_BROADCAST, "Done with parallel broadcast ["
                    + mQueueName + "] " + r);
        }
        ...

这个方法的实现还是很长的,我么主要看注释1处,它调用了deliverToRegisteredReceiverLocked

private void deliverToRegisteredReceiverLocked(BroadcastRecord r,
            BroadcastFilter filter, boolean ordered, int index) {
    try {
            if (DEBUG_BROADCAST_LIGHT) Slog.i(TAG_BROADCAST,
                    "Delivering to " + filter + " : " + r);
            if (filter.receiverList.app != null && filter.receiverList.app.inFullBackup) {
                // Skip delivery if full backup in progress
                // If it's an ordered broadcast, we need to continue to the next receiver.
                if (ordered) {
                    skipReceiverLocked(r);
                }
            } else {
                r.receiverTime = SystemClock.uptimeMillis();
                maybeAddAllowBackgroundActivityStartsToken(filter.receiverList.app, r);
                //注释1
                performReceiveLocked(filter.receiverList.app, filter.receiverList.receiver,
                        new Intent(r.intent), r.resultCode, r.resultData,
                        r.resultExtras, r.ordered, r.initialSticky, r.userId);
                // parallel broadcasts are fire-and-forget, not bookended by a call to
                // finishReceiverLocked(), so we manage their activity-start token here
                if (r.allowBackgroundActivityStarts && !r.ordered) {
                    postActivityStartTokenRemoval(filter.receiverList.app, r);
                }
            }
            if (ordered) {
                r.state = BroadcastRecord.CALL_DONE_RECEIVE;
            }
        }
    }

紧接着会调用注释1处的performReceiveLocked方法,该方法实现如下:

void performReceiveLocked(ProcessRecord app, IIntentReceiver receiver,
            Intent intent, int resultCode, String data, Bundle extras,
            boolean ordered, boolean sticky, int sendingUser)
            throws RemoteException {
        // Send the intent to the receiver asynchronously using one-way binder calls.
        if (app != null) {
            if (app.thread != null) {
                // If we have an app thread, do the call through that so it is
                // correctly ordered with other one-way calls.
                try {
                    //注释1
                    app.thread.scheduleRegisteredReceiver(receiver, intent, resultCode,
                            data, extras, ordered, sticky, sendingUser, app.getReportedProcState());
                // TODO: Uncomment this when (b/28322359) is fixed and we aren't getting
                // DeadObjectException when the process isn't actually dead.
                //} catch (DeadObjectException ex) {
                // Failed to call into the process.  It's dying so just let it die and move on.
                //    throw ex;
                } catch (RemoteException ex) {
                    // Failed to call into the process. It's either dying or wedged. Kill it gently.
                    synchronized (mService) {
                        Slog.w(TAG, "Can't deliver broadcast to " + app.processName
                                + " (pid " + app.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);
        }
    }

最终会执行app.thread对象的scheduleRegisteredReceiver方法,app.thread对象是ActivityThread的内部类对象ApplicationThread,这个在前面几篇文章多次提到过,在这里也就不做过多的解释,我们继续跟进ApplicationThread对象的scheduleRegisteredReceiver方法,它的实现如下:

ApplicationThread中的流程
 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);
        }

在客户端更新进程状态之后经过短暂的停留,随着receiver对象的performReceive的调用流程再次回到服务端进程,receiver是不是熟悉?就是在前面我们在讲ContextImpl对象的registerReceiverInternal方法的时候所提到的ReceiverDispatcher.InnerReceiver对象,下面我们来看看InnerReceiver对象的performReceive方法的实现,如下所示:

InnerReceiver中的流程
 @Override
            public void performReceive(Intent intent, int resultCode, String data,
                    Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
                final LoadedApk.ReceiverDispatcher rd;
                if (intent == null) {
                    Log.wtf(TAG, "Null intent received");
                    rd = null;
                } else {
                    rd = mDispatcher.get();
                }
                if (ActivityThread.DEBUG_BROADCAST) {
                    int seq = intent.getIntExtra("seq", -1);
                    Slog.i(ActivityThread.TAG, "Receiving broadcast " + intent.getAction()
                            + " seq=" + seq + " to " + (rd != null ? rd.mReceiver : null));
                }
                if (rd != null) {
                    //注释1
                    rd.performReceive(intent, resultCode, data, extras,
                            ordered, sticky, sendingUser);
                } else {
                    // The activity manager dispatched a broadcast to a registered
                    // receiver in this process, but before it could be delivered the
                    // receiver was unregistered.  Acknowledge the broadcast on its
                    // behalf so that the system's broadcast sequence can continue.
                    if (ActivityThread.DEBUG_BROADCAST) Slog.i(ActivityThread.TAG,
                            "Finishing broadcast to unregistered receiver");
                    IActivityManager mgr = ActivityManager.getService();
                    try {
                        if (extras != null) {
                            extras.setAllowFds(false);
                        }
                        mgr.finishReceiver(this, resultCode, data, extras, false, intent.getFlags());
                    } catch (RemoteException e) {
                        throw e.rethrowFromSystemServer();
                    }
                }
            }

在performReceive方法的注释1处会调用ReceiverDispatcher对象的performReceive方法,该方法如下所示:

public void performReceive(Intent intent, int resultCode, String data,
                Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
            final Args args = new Args(intent, resultCode, data, extras, ordered,
                    sticky, sendingUser);
            if (intent == null) {
                Log.wtf(TAG, "Null intent received");
            } else {
                if (ActivityThread.DEBUG_BROADCAST) {
                    int seq = intent.getIntExtra("seq", -1);
                    Slog.i(ActivityThread.TAG, "Enqueueing broadcast " + intent.getAction()
                            + " seq=" + seq + " to " + mReceiver);
                }
            }
            //注释1
            if (intent == null || !mActivityThread.post(args.getRunnable())) {
                if (mRegistered && ordered) {
                    IActivityManager mgr = ActivityManager.getService();
                    if (ActivityThread.DEBUG_BROADCAST) Slog.i(ActivityThread.TAG,
                            "Finishing sync broadcast to " + mReceiver);
                    args.sendFinished(mgr);
                }
            }
        }

在注释1处给ActivityThread的消息管理器发送一个args.getRunnable类型回调的消息,下面就是该回调的具体实现:

public final Runnable getRunnable() {
                return () -> {
                    final BroadcastReceiver receiver = mReceiver;
                    final boolean ordered = mOrdered;

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

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

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

                    Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "broadcastReceiveReg");
                    try {
                        ClassLoader cl = mReceiver.getClass().getClassLoader();
                        intent.setExtrasClassLoader(cl);
                        intent.prepareToEnterProcess();
                        setExtrasClassLoader(cl);
                        receiver.setPendingResult(this);
                        //注释1
                        receiver.onReceive(mContext, intent);
                    } catch (Exception e) {
                        if (mRegistered && ordered) {
                            if (ActivityThread.DEBUG_BROADCAST) Slog.i(ActivityThread.TAG,
                                    "Finishing failed broadcast to " + mReceiver);
                            sendFinished(mgr);
                        }
                        if (mInstrumentation == null ||
                                !mInstrumentation.onException(mReceiver, e)) {
                            Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
                            throw new RuntimeException(
                                    "Error receiving broadcast " + intent
                                            + " in " + mReceiver, e);
                        }
                    }

                    if (receiver.getPendingResult() != null) {
                        finish();
                    }
                    Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
                };
            }

在注释1处广播接收器BroadcastReceiver的onReceive方法被回调了,至此整个广播接收器的注册、广播的发送、广播的接收所有的流程就全部走完了,最后我画了两幅流程图,方便大家对整个流程的理解。

总结

注册流程
在这里插入图片描述

ContextWraper.registerReceiver
ContextImpl.registerReceiver
ContextImpl.registerReceiverInternal
ActivityManagerService.registerReceiver

发送接收流程
在这里插入图片描述

ContextWraper.sendBroadcast
ContextImpl.sendBroadcast
ActivityManagerService.broadcastIntent
ActivityManagerService.broadcastIntentLocked
BroadcastQueue.scheduleBroadcastsLocked
BroadcastQueue.processNextBroadcastLocked
BroadcastQueue.deliverToRegisteredReceiverLocked
BroadcastQueue.performReceiveLocked
ApplicationThread.scheduleRegisteredReceiver
InnerReceiver.performReceive
ReceiverDispatcher.performReceive
BroadcastReceiver.onReceive

问题反馈

在使用学习中有任何问题,请留言,或加入Android、Java开发技术交流群

上一篇下一篇

猜你喜欢

热点阅读