BroadcastReceiver的源码分析

简介: android提供了广播机制,通过BroadcastReceiver可以在不同的进程间传递消息。类似于观察者模式,A应用通过注册广播表示A对消息subject感兴趣,当B应用发出subject类型的消息的时候,A应用就能收到对应的消息。

android提供了广播机制,通过BroadcastReceiver可以在不同的进程间传递消息。类似于观察者模式,A应用通过注册广播表示A对消息subject感兴趣,当B应用发出subject类型的消息的时候,A应用就能收到对应的消息。

android提供静态和动态两种方式进行消息注册,静态注册指的是在AndroidManifest.xml中进行注册,动态注册指的是在Activity通过registerReceiver的方式进行广播注册。

静态广播注册流程

静态广播注册指的是在AndroidManifest.xml注册Receiver,当Apk安装时会将静态注册的Receiver信息注册到PMS中,APK的安装流程(https://www.jianshu.com/p/953475cea991)如下:

img_47f9af2b2d4df381166bec1d6ccdd5d9.png
APK安装流程

其中installPackageLI完成了Apk的解析,生成了Package对象,scanPackageLi包括四大组件注册之类的操作。

img_6744e0c68bdeddac14b880581737c087.png
PMS.scanPackageDirtyLI注册静态广播

解析到APK里的静态广播会注册到PMS的mReceivers对象中,mReceivers类型为ActivityIntentResolver。

动态广播注册流程

Activity通过registerReceiver方式进行广播注册,注册流程如下:

img_e462376d8b9cd6d59914b4a470d15e71.png
registerReceiver流程

ContextImpl.registerReceiverInternal

img_9c1bba5dec41715fba98f9d5bf04f230.png
ContextImpl.registerReceiverInternal

该函数根据BroadcastReceiver对象生成IIntentReceiver对象,该对象和ApplicationThread的功能一样,试想一下,APP进程向AMS进程注册广播,当AMS收到广播向APP进程分发时需要用到Binder调用,IIntentReceiver就是进行跨进程调用的。

img_9943ed5b8f75c0d254b32cc0399d8268.png
AMS.registerReceiver

AMS将IIntentReceiver保存到mReisterdReceivers中,最终保存到mReceiverResolver.addFilter(bf);中。

sendBroadcast发送广播

img_ffc546bf2daaef71d17b5e905a29ce64.jpe
sendBroascast流程

发送广播最终走到了AMS.broadcastIntentLocked,其中核心的代码如下所示:

img_443bd0c7192d975147b24c7693baaa98.png
AMS.broadcastIntentLocked

broadcastIntentLocked中receivers表示静态注册的广播,通过collectReceiverComponents从PMS那里获取;registerdReceivers表示动态注册的广播,从mReceiverResolver那里获取。在获取到要接受所有广播后,就调用如下函数进行广播分发。

img_427ad0c8090bc913223424e2ad1da1c1.png
广播分发

scheduleBroadcastsLocked开始进行广播发送

img_1e92c46a8996b4bbdbd17ca009c9dfe1.png
BroadcastQueue.scheduleBroadcastsLocked

Handler消息最终调用了BroadcastQueue.processNextBroadcast,然后调用了performReceiveLocked,

img_9138edcd6643fa0fd5c4389ae014e87e.png
processNextBroadcast

processNextBroadcast调用了performReceiverLocked

img_33abe4993f60029de5d324de280f925f.png
performReceiverLocked

performReceiverLocked继续调用IItentReceiver.performReceiver,该调用的Binder方式,

img_e8208ec92c18e3006a653f1eaa261283.png
IItentReceiver.performReceiver

最终调用了Args.run

img_8ce322886298bd74f2866264afe2dc31.png
Args.run

Args.run通过类加载器加载Receiver对象,并最终调用onReceive函数,至此,广播发送完成。

目录
相关文章
|
存储 前端开发 Android开发
Android | LiveData 源码分析
Android | LiveData 源码分析
|
Android开发 容器 Python
DialogFragment源码分析
目录介绍 1.最简单的使用方法 1.1 官方建议 1.2 最简单的使用方法 1.3 DialogFragment做屏幕适配 2.源码分析 2.1 DialogFragment继承Fragment 2.
1183 0
|
Android开发 容器
【Android 事件分发】ItemTouchHelper 源码分析 ( OnItemTouchListener 事件监听器源码分析 二 )(三)
【Android 事件分发】ItemTouchHelper 源码分析 ( OnItemTouchListener 事件监听器源码分析 二 )(三)
145 0
【Android 事件分发】ItemTouchHelper 源码分析 ( OnItemTouchListener 事件监听器源码分析 二 )(三)
|
Android开发
【Android 事件分发】ItemTouchHelper 源码分析 ( OnItemTouchListener 事件监听器源码分析 二 )(二)
【Android 事件分发】ItemTouchHelper 源码分析 ( OnItemTouchListener 事件监听器源码分析 二 )(二)
181 0
|
Android开发 开发者
【Android 事件分发】ItemTouchHelper 源码分析 ( OnItemTouchListener 事件监听器源码分析 二 )(一)
【Android 事件分发】ItemTouchHelper 源码分析 ( OnItemTouchListener 事件监听器源码分析 二 )(一)
235 0
|
Android开发
【Android 事件分发】ItemTouchHelper 源码分析 ( OnItemTouchListener 事件监听器源码分析 )(三)
【Android 事件分发】ItemTouchHelper 源码分析 ( OnItemTouchListener 事件监听器源码分析 )(三)
107 0
|
Android开发
【Android 事件分发】ItemTouchHelper 源码分析 ( OnItemTouchListener 事件监听器源码分析 )(一)
【Android 事件分发】ItemTouchHelper 源码分析 ( OnItemTouchListener 事件监听器源码分析 )(一)
231 0
|
Java Android开发
【Android 启动过程】Activity 启动源码分析 ( ActivityThread -> Activity、主线程阶段 二 )
【Android 启动过程】Activity 启动源码分析 ( ActivityThread -> Activity、主线程阶段 二 )
226 0
|
Java Android开发
【Android 启动过程】Activity 启动源码分析 ( ActivityThread -> Activity、主线程阶段 一 )
【Android 启动过程】Activity 启动源码分析 ( ActivityThread -> Activity、主线程阶段 一 )
482 0
IntentService源码分析
我们知道Service是运行在主线程的,主线程中不能进行耗时操作,否则会发生ANR。Service中的发生ANR的超时时间是20s。 有时候我们需要应用在后台默默做一些任务,例如上传文件等。如果我们采用Service,则需要我们自己手动开启新的线程。如果我们不想 自己开启线程怎么办,IntentService就出现了。