Android BroadcastReceiver的工作流程源码分析(8.0)

一,写在前面

       本篇文章会从源码角度分析广播的工作流程,具体来说是分为两部分:广播的注册,发送广播。在阅读本篇文章前,建议先了解Activity,Service相关的工作流程。本篇文章将不再分析工作流程中的重复细节,参考文章:

二,广播的注册,交给ContextImpl

        广播的注册分为静态注册,以及动态注册。静态注册是在xml中配置<receiver>节点,在应用程序启动后会解析xml文件,具体的注册流程是交给PackagerManagerService来处理。本篇文章主要分析广播的动态注册,也就是在Java代码中调用registerReceiver方法来注册广播,开发中具体的使用这里不再介绍。
       不管是在Activity,还是Service中注册广播,都是调用ContextWrapper$registerReceiver方法。其中,ContextWrapper是Context的一个子类,在抽象类Context中定义了抽象方法registerReceiver,具体实现在子类ContextWrapper中。
       查看ContextWrapper$registerReceiver源码:
@Override
    public Intent registerReceiver(
        BroadcastReceiver receiver, IntentFilter filter) {
        return mBase.registerReceiver(receiver, filter);
    }
       第4行,变量mBase是Context类型,而Context是一个抽象类,其实mBase的具体实现类是ContextImpl。至于具体原因,可以查看文章  Android Activity的启动流程源码解析(8.0) ,这里不再重复阐述。

       查看ContextImpl相关源码:
    @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);
    }

    //继续查看...

    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();
            }
        }
        
	//...code

            final Intent intent = ActivityManager.getService().registerReceiver(
                    mMainThread.getApplicationThread(), mBasePackageName, rd, filter,
                    broadcastPermission, userId, flags);           
          
        //...code
    }
       第17行,ContextImpl$registerReceiver有多个重载方法,但最终都会调用ContextImpl$registerReceiverInternal方法。
       第24行,mMainThread是一个ActivityThread类型的变量,它的实例化在ContextImpl的构造方法中。mMainThread.getHandler()返回一个H类型的对象,H是ActivityThread的内部类,继承了Handler。值得一提的是,在启动Activity,Service的工作流程中,都会创建一个上下文环境,也就是会创建ContextImpl对象。具体分析,见文章  Android Activity的启动流程源码解析(8.0) ,这里不再重复阐述。
       
       第26行,变量mPackageInfo是一个LoadedApk的变量,这里是将BroadcastReceiver对象封装到ReceiverDispatcher中,并最终返回IIntentReceiver类型的对象。有意思的是,ReceiverDispatcher与绑定服务中的ServiceDispatcher比较类似,都是将组件对象进行封装,并返回一个Binder对象,用于实现组件对
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值