android四大组件启动流程-BroadcastReceiver启动流程(基于android 6.0)

前面已经写过Activity的启动流程:http://blog.csdn.net/newhope1106/article/details/53355189 和 Service的启动流程:http://blog.csdn.net/newhope1106/article/details/53843809 ,本篇是关于广播的,其实标题写得不准确,广播的注册、发送和接收应该是一起,下面开始讲解内容吧。
摘要由CSDN通过智能技术生成
前面已经写过Activity的启动流程: http://blog.csdn.net/newhope1106/article/details/53355189 和 Service的启动流程: http://blog.csdn.net/newhope1106/article/details/53843809 ,本篇是关于广播的,其实标题写得不准确,广播的注册、发送和接收应该是一起,下面开始讲解内容吧。
广播在android系统中,使用非常频繁,可以说是耦合度极低的一种通信方式。操作系统一方面为了让任务执行互不干扰,即使某个任务挂了,也不会影响其他的任务,因此才有了进程,但是任务之间通常又是相关的,又需要涉及到进程间的通信,当然进程间通信的方式有很多种,管道、信号、消息队列、共享内存等,socket也算是一种,android采用的是Binder,但是我们应用层开发的时候,基本上没有让我们直接操作Binder,也就是直接参与到进程间的通信细节,这样会给我们一种错觉,进程好像是一体的,通信很简单,android系统一方面将不同的任务放在不同的进程中,一方面又模糊进程的概念,让它看起来就是一个整体,确实相当了不起。废话不多说,直接看分析。
一、广播的注册过程

四大组件中,广播是唯一一个可以不需要在AndroidMenifest.xml中注册的组件,根据是否在AndroidMenifest.xml注册,分为静态广播和动态广播,此外还分为前台广播和后台广播,也分为有序广播和无序广播,分类挺多的,四大组件如果是在AndroidMenifest.xml注册的,注册过程由PMS来负责,我们这边只管动态广播,也就是在代码中注册的。先来看一个简单的广播注册例子:

//new出上边定义好的BroadcastReceiver
MyBroadCastReceiver smsBroadCastReceiver = new MyBroadCastReceiver();

//实例化过滤器并设置要过滤的广播  
IntentFilter intentFilter = new IntentFilter("android.provider.Telephony.SMS_RECEIVED");

//注册广播   
mContext.registerReceiver(smsBroadCastReceiver,intentFilter);

一个广播接收器,和一个过滤器,重点不是这个,主要讲register的过程,在Service的启动流程中,我们已经知道mContext就是ContextImpl,这里同样是这个类,从Activity和Service的启动流程应该已经看出来,基本都是套路了,涉及到进程间通信的,先转化为实现IBinder的对象,然后扔给AMS调用,接着再扔给某个对应的类来专门处理。广播的注册过程除了最后一个不满足(发送和接收是满足的),其实也是这个套路。先贴出几个调用的接口,最后都调用到了registerReceiverInternal里面。
@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());
    }

    @Override
    public Intent registerReceiverAsUser(BroadcastReceiver receiver, UserHandle user,
            IntentFilter filter, String broadcastPermission, Handler scheduler) {
        return registerReceiverInternal(receiver, user.getIdentifier(),
                filter, broadcastPermission, scheduler, getOuterContext());
    }
再来看看这个方法的内容,由于广播涉及到进程间通信,它首先会讲receiver通过LoadedApk来转化为实现了IBinder接口的对象IIntentReceiver,再扔给AMS处理。
    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) {
                    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 {
            return ActivityManagerNative.getDefault().registerReceiver(
                    mMainThread.getApplicationThread(), mBasePackageName,
                    rd, filter, broadcastPermission, userId);
        } catch (RemoteException e) {
            return null;
        }
    }
可以关注下面这个代码,mPackageInfo是LoadedApk这个类的对象,具体代码是什么,感兴趣的可以自己看一下源码
    rd = mPackageInfo.getReceiverDispatcher(
                    receiver, context, scheduler,
                    mMainThread.getInstrumentation(), true);
至于IIntentReceiver,它是在AIDL中写的,android编译的时候会把它先生成对应的类,可以看到只有一个performReceive接口,不多说,继续往下。
oneway interface IIntentReceiver {
    void performReceive(in Intent intent, int resultCode, String data,
            in Bundle extras, boolean ordered, boolean sticky, int sendingUser);
}
最后广播的注册过程都是调用到AMS的registerReceiver方法中,下面是方法的关键部分,最终receiver和intentfilter都被保存了起来。
   public Intent registerReceiver(IApplicationThread caller, String callerPackage,
            IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
        ......

        synchronized (this) {
            if (callerApp != null && (callerApp.thread == nul
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值