0
点赞
收藏
分享

微信扫一扫

Android源码 --- BroadCast源码分析

小北的爹 2022-02-25 阅读 164

BroadCastReciver 源码分析

上篇记录了activity启动流程的关键节点代码,本篇同样只是记录广播源码的关键节点代码

一、发送广播

broadCast 分为普通广播有序广播普通广播 发送后注册该广播的接收器都能接收到,而有序广播不同的是会根据接收器的优先级依次收到广播,并可中断广播继续向下发送

以下做了一个简单的脑图,做为流程图,可以大体看明白广播的传递流程

在这里插入图片描述

关键节点源码

sendBroadCast只是在Context中做了定义,而Context的实现类是Contextimpl,以下代码我们可以看到是直接将参数给到了AMS处理

    @Override
    public void sendBroadcast(Intent intent, String receiverPermission, int appOp) {
        warnIfCallingFromSystemProcess();
        String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
        String[] receiverPermissions = receiverPermission == null ? null
                : new String[] {receiverPermission};
        try {
            intent.prepareToLeaveProcess(this);
            //调用AMS
            ActivityManager.getService().broadcastIntent(
                    mMainThread.getApplicationThread(), intent, resolvedType, null,
                    Activity.RESULT_OK, null, null, receiverPermissions, appOp, null, false, false,
                    getUserId());
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
        }
    } 

通过层层调用我们在方法broadcastIntentLocked中会看到以下关键代码:
在这里插入图片描述
其中 queue.enqueueParallelBroadcastLocked的实现,将该条记录存放到了列表中

    public void enqueueParallelBroadcastLocked(BroadcastRecord r) {
        this.mParallelBroadcasts.add(r);
    }

scheduleBroadcastsLocked的实现,这里通过handler发送了一个消息

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

通过这个消息会调用processNextBroadcast该方法,会调用到deliverToRegisteredReceiverLocked该方法,通过该方法会调用到performReceiveLocked方法
在这里插入图片描述
performReceiveLocked方法:

    private static void performReceiveLocked(ProcessRecord app, IIntentReceiver receiver, Intent intent, int resultCode, String data, Bundle extras, boolean ordered, boolean sticky, int sendingUser) throws RemoteException {
        if (app != null && app.thread != null) {
        //IApplicationThread 的实现ActivityTread
        //这里开始从AMS回调到应用中
           app.thread.scheduleRegisteredReceiver(receiver, intent, resultCode, data, extras, ordered, sticky, sendingUser);
        } else {
            receiver.performReceive(intent, resultCode, data, extras, ordered, sticky, sendingUser);
        }

    }

ActivityThread中的实现:

        public void scheduleRegisteredReceiver(IIntentReceiver receiver, Intent intent, int resultCode, String dataStr, Bundle extras, boolean ordered, boolean sticky, int sendingUser) throws RemoteException {
        //IIntentReceiver的实现在LoadedApk类
            receiver.performReceive(intent, resultCode, dataStr, extras, ordered, sticky, sendingUser);
        }

LoadedApk中的实现,开始分发广播

        public void performReceive(Intent intent, int resultCode, String data, Bundle extras, boolean ordered, boolean sticky, int sendingUser) {
            LoadedApk.ReceiverDispatcher.Args args = new LoadedApk.ReceiverDispatcher.Args(intent, resultCode, data, extras, ordered, sticky, sendingUser);
            if (!this.mActivityThread.post(args) && this.mRegistered && ordered) {
                IActivityManager mgr = ActivityManagerNative.getDefault();
                args.sendFinished(mgr);
            }

        }

args 这个Runnable核心逻辑代码:

            public void run() {
                BroadcastReceiver receiver = ReceiverDispatcher.this.mReceiver;
                boolean ordered = this.mOrdered;
                IActivityManager mgr = ActivityManagerNative.getDefault();
                Intent intent = this.mCurIntent;
                this.mCurIntent = null;
                if (receiver != null && !ReceiverDispatcher.this.mForgotten) {
                    Trace.traceBegin(64L, "broadcastReceiveReg");

                    try {
                        ClassLoader cl = ReceiverDispatcher.this.mReceiver.getClass().getClassLoader();
                        intent.setExtrasClassLoader(cl);
                        this.setExtrasClassLoader(cl);
                        receiver.setPendingResult(this);
                        receiver.onReceive(ReceiverDispatcher.this.mContext, intent);
                    } catch (Exception var6) {
                        if (ReceiverDispatcher.this.mRegistered && ordered) {
                            this.sendFinished(mgr);
                        }

                        if (ReceiverDispatcher.this.mInstrumentation == null || !ReceiverDispatcher.this.mInstrumentation.onException(ReceiverDispatcher.this.mReceiver, var6)) {
                            Trace.traceEnd(64L);
                            throw new RuntimeException("Error receiving broadcast " + intent + " in " + ReceiverDispatcher.this.mReceiver, var6);
                        }
                    }

                    if (receiver.getPendingResult() != null) {
                        this.finish();
                    }

                    Trace.traceEnd(64L);
                } else {
                    if (ReceiverDispatcher.this.mRegistered && ordered) {
                        this.sendFinished(mgr);
                    }

                }
            }
        }

自此整个广播发送流程就结束了

二、 注册接收广播

注册比较简单,通过将参数交给AMS,保存到列表中,注册成功

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();
                }
                rd = new LoadedApk.ReceiverDispatcher(
                        receiver, context, scheduler, null, true).getIIntentReceiver();
            }
        }
        try {
        //AMS处理
            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();
        }
    }
举报

相关推荐

0 条评论