【学习】Android四大组件启动流程(3)——BroadcastReceiver的工作过程

本文深入探讨了Android中BroadcastReceiver的工作流程,包括静态和动态注册的细节,以及广播的发送和接收机制。从注册过程的PMS解析到AMS中的广播管理,再到接收广播时的onReceive方法调用,全面剖析了广播通信的全过程。
摘要由CSDN通过智能技术生成

BroadcastReceiver的工作过程

1.广播的注册过程
2.广播的发送和接收过程

回顾广播的使用方法

1.定义广播接收者
继承BroadcastReceiver并重写onReceive方法

2.注册广播接收者
静态注册
在AndroidManifest文件中静态注册

在这里插入图片描述

动态注册(需要在合适的时机解注册)

在这里插入图片描述

3.通过send方法发送广播

在这里插入图片描述

广播注册、发送和接受的大致流程图

在这里插入图片描述

广播的注册过程

静态注册
在应用安装时由系统自动完成注册,具体来说是PMS(PackageManagerService)来完成整个注册过程,其他三大组件也是在应用安装时由PMS解析并注册的。

动态注册
从ContextWrapper的registerReceiver方法开始,它把注册过程交给了ContextImpl来完成
在这里插入图片描述

它又把注册过程交给registerReceiverInternal方法

在这里插入图片描述

registerReceiverInternal方法实现如下

在这里插入图片描述

系统首先从mPackageInfo获取IIntentReceiver对象rd,然后再采用跨进程的方式向AMS发送广播注册的请求。不采用BroadcastReceiver是因为上述注册过程是一个进程间通信的过程,而它作为一个安卓组件时不能直接跨进程传递的,所以要通过IIntentReceiver来中转。IIntentReceiver必须是一个Binder接口,它的具体实现是LoadApk.ReceiverDispatcher.InnerReceiver,ReceiveDispatcher的内部同时保存了BroadcastReceiver和InnerReceiver,这样当接收到广播时,ReceiverDispatcher可以很方便地调用BroadcaseReceiver的onReceive方法.可以发现BroadcastReceiver的这个过程和Service的实现原理类似,Service也有一个ServiceDispatcher的类,并且其内部类InnerConnection也是一个Binder接口,同样也是为了进程间通信。下面看一下ReceiveDispatcher的getIIntentReceiver的实现

在这里插入图片描述

getReceiveDispatcher方法重新创建了一个ReceiverDispatcher对象并将其保存的InnerReceiver对象作为返回值返回,其中InnerReceiver对象和BroadcastReceiver都是在ReceiverDispatcher的构造方法中被保存起来的。

注册广播的真正实现过程是在AMS中,所以我们需要看一下AMS的registerReceiver方法(太长,只看核心代码)
在这里插入图片描述

最终把远程的InnerReceiver对象以及IntentFilter对象存储起来,这样子整个广播的注册过程就完成了

广播的发送和接收过程

当通过send方法来发送广播时,AMS会查找出匹配的广播接收者并将广播发送给它们处理。广播的发送有几种类型:普通广播 有序广播 粘性广播(已经弃用),但他们流程是类似的,因此这里只分析普通广播

广播的发送
开始于ContextWrapper的sendBroadcast方法,不用Context中的send方法是因为Context的send方法是一个抽象方法。ContextWrapper同样把事情交给ContextImpl处理
在这里插入图片描述

它向AMS发起了一个异步请求用于发送广播,下面之间看AMS的broadcastIntent方法
在这里插入图片描述

它调用了broadcastIntentLocked方法(很长,截取部分了解)

在这里插入图片描述

这表示默认情况下广播不会发送给已经停止的应用

两个标签控制广播是否要对处于停止状态的应用起作用

FLAG_INCLUDE_STOPPED_PACKAGES
表示包含已经停止的应用,这个时候广播会发送给已经停止的应用

FLAG_EXCLUDE_STOPPED_PACKAGES
表示不包含已经停止的应用,这个时候广播不会发送给已经停止的应用

继续上面的方法解析
在这里插入图片描述

它会根据intent-filiter查找出匹配的广播接收者并经过一系列的条件过滤,最终会将满足条件的广播接收者添加到BroadcastQueue中,接着BroadcastQueue就会将广播发送给相应的广播接收者

看一下BroadcastQueue中广播的发送过程
在这里插入图片描述

它发送了一个BROADCAST_INTENT_MSG类型的消息,BroadcastQueue收到消息后会调用processNextBroadcast方法,BroadcastQueue的processNextBroadcast方法对普通广播的处理如下
在这里插入图片描述

无序广播存储在mParallelBroadcasts中,系统会遍历mParalledBroadcasts并将其中的广播发送给它们所有的接收者,具体的发送过程通过deliverToRegisteredReceiverLocked方法实现,它将一个广播发送给一个特定的接收者,它内部调用了performReceiveLocked方法来完成具体的发送过程

在这里插入图片描述

由于接收广播会调起应用程序,因此app.thread不为null,这里的app.thread仍然是ApplicationThread。它调用了scheduleRegisteredReceiver方法
在这里插入图片描述

IIntentrReceiver的performReceive方法会调用LoadedApk.ReceiverDispatcher的performReceive方法
在这里插入图片描述

它创建了一个Args对象并用mActivityThread的post方法来执行Args中的逻辑,而Args实现了Runnable接口。mActivityThread是一个Hnalder,它其实就是ActivityThread中的mH,mH就是ActivityThread的内部类H。

在Args的run方法中
在这里插入图片描述

这个时候Broadcast的onReceive方法被执行,也就是说应用已经收到广播了,同时onReceive是在广播接收者的主线程中被调用的。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值