Android面试——BroadcastReceiver篇

注意点:

1. 从Android 8.0开始 ,限制了隐式广播

隐式广播:就是Intent使用action的广播,没有指定包名类名;

 

 

 

一:广播的分类和使用场景

分类:

1. 普通广播:通过Context.sendBroadcast()发送,可并行处理

2. 系统广播:系统发送的广播,只需要注册广播接收器,并定义好action等待接收广播

3. 有序广播:发出的广播会被接收器按照先后顺序进行接收,发送方式为sendOrderedBroadcast(intent); 广播接受者接收的顺序规则:按照Priority属性值排序,Priority相同者,动态注册的广播优先;

4. APP应用内广播(Local Broadcast):由于广播可以跨进程的特性,导致应用可能不断收到来自其他应用的广播,或者别的应用接收到当前应用的私密广播;解决方法为使用应用内广播;也称局部广播,接收者和发送者同属于一个APP,

  使用1:注册广播时设置exported属性为false;在广播发送接收时,增加权限,用于权限验证;发送广播时执行广播接收器的包名

  使用2:使用封装好的LocalBroadcastManager,这种方式的广播只能动态注册,不能静态注册

使用场景:

同一 App 内部的不同组件之间的消息通信(单个进程);
不同 App 之间的组件之间消息通信;
Android系统在特定情况下与App之间的消息通信,如:网络变化、电池电量、屏幕开关等;

 

二:广播的两种注册方式的区别

静态注册:常驻系统,不受组件生命周期影响,即便应用退出,广播还是可以被接收,耗电、占内存。

动态注册:非常驻,跟随组件的生命变化,组件结束,广播结束。在组件结束前,需要先移除广播,否则容易造 成内存泄漏。

 

三:广播发送和接收的原理

动态注册:

1. 创建对象 LoadedApk.ReceiverDispatcher.InnerReceiver,该对象继承自IIntentReceiver.Stub,是一个本地Binder对象,提供onTransact接口接收请求

2. 

将IIntentReceiver对象和注册所传的IntentFilter对象发送给AMS。 AMS记录IIntentReceiver、IntentFilter和注册的进程ProcessRecord,并建立起它们的对应关系

3. 当有广播发出时,AMS根据广播iIntent所携带的IntentFilter找到IIntentReceiver和ProcessRecord,然后回调App的ApplicationThread对象的scheduleRegisteredReceiver,将IIntentReceiver和广播的intent一并传给App,App直接调用IIntentReceiver的performReceive。

4.因为广播是通过binder线程回调到接收进程的,接收进程通过ActivityThread里的H这个Handler将调用转到主线程,然后回调BroadcastReceiver的onReceive。

静态注册:

静态注册是通过在Manifest文件中声明实现了BroadcastReceiver的自定义类和对应的IntentFilter,来告诉PMS(PackageManagerService)这个App所注册的广播。
当AMS接收到广播后,会查找所有动态注册的和静态注册的广播接收器,静态注册的广播接收器是通过PMS(PackageManagerService)发现的,PMS找到对应的App
对应进程已经创建,直接调用App的ApplicationThread对象的scheduleReceiver

对应进程尚未创建,先启动App进程,App进程启动后回调AMS的attachApplication,attachApplication则继续派发刚才的广播App这边收到调用后会先通过Handler转到主线程,然后根据AMS传过来的参数实例化广播接收器的类,接着调用广播接收器的onReceive。

 

 

posted @ 2022-02-26 18:31  向着内核前进!  阅读(321)  评论(0编辑  收藏  举报