Moosphan / Android-Daily-Interview

:pushpin:每工作日更新一道 Android 面试题,小聚成河,大聚成江,共勉之~

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

2019-03-22:BroadcastReceiver 与 LocalBroadcastReceiver 有什么区别?

Moosphan opened this issue · comments

2019-03-22:BroadcastReceiver 与 LocalBroadcastReceiver 有什么区别?
commented

BroadcastReceiver是针对应用间、应用与系统间、应用内部进行通信的一种方式
LocalBroadcastReceiver仅在自己的应用内发送接收广播,也就是只有自己的应用能收到,数据更加安全广播只在这个程序里,而且效率更高。
BroadcastReceiver 使用
1.制作intent(可以携带参数)
2.使用sendBroadcast()传入intent;
3.制作广播接收器类继承BroadcastReceiver重写onReceive方法(或者可以匿名内部类啥的)
4.在java中(动态注册)或者直接在Manifest中注册广播接收器(静态注册)使用registerReceiver()传入接收器和intentFilter
5.取消注册可以在OnDestroy()函数中,unregisterReceiver()传入接收器
LocalBroadcastReceiver 使用
1.LocalBroadcastReceiver不能静态注册,只能采用动态注册的方式。
在发送和注册的时候采用,LocalBroadcastManager的sendBroadcast方法和registerReceiver方法

  • BroadcastReceiver 是跨应用广播,利用Binder机制实现,支持动态和静态两种方式注册方式。
  • LocalBroadcastReceiver 是应用内广播,利用Handler实现,利用了IntentFilter的match功能,提供消息的发布与接收功能,实现应用内通信,效率和安全性比较高,仅支持动态注册。

广播细分为三种:

  1. 普通广播
  2. 有序广播
  3. 本地广播

普通广播是什么?

  1. 调用sendBroadcast()发送

有序广播是什么?

  1. 调用sendOrderedBroadcast()发送
  2. 广播接收者会按照priority优先级从大到小进行排序
  3. 优先级相同的广播,动态注册的广播优先处理
  4. 广播接收者还能对广播进行截断和修改

本地广播的优点?

  1. 效率更高。
  2. 发送的广播不会离开我们的应用,不会泄露关键数据。
  3. 其他程序无法将广播发送到我们程序内部,不会有安全漏洞。

补充说明一点,现在BroadcastReceiver也不推荐使用静态注册了,8.0之后限制了绝大部分广播只能使用动态注册

应用内广播现在还有人用吗?已经被EventBus类似的事件替换了吧?

1.本地广播只在app内部传播,属于进程内通信。而BroadcastReceiver则是全局通信,是进程间通信。前者更为安全。
2.本地广播高效,内部通过handler,而BroadcastReceiver需要binder通信。
3.本地广播只支持动态注册,而系统广播除了动态注册还可以注册到manifest中。

BroadcastReceiver(广播接收者):是跨应用广播,利用Binder机制实现。
静态注册:
(1)在清单文件中,通过标签声明;
(2)在Android3.1开始,对于接收系统广播的BroadcastReceiver,App进程退出后,无法接收到广播;对于自定义的广播,可以通过重写flag的值,使得即使App进程退出,仍然可以接收到广播。
(3)静态注册的广播是由PackageManagerService负责。

动态注册:1.在代码中注册,程序运行的时候才能进行;2.跟随组件的生命周期;3.动态注册的广播是由AMS(ActivityManagerService)负责的。
注意:对于动态注册,最好在Activity的onResume()中注册,在onPause()中注销。在系统内存不足时,onStop()、onDestory()可能不会执行App就被销毁,onPause()在App销毁前一定会被执行,保证广播在App销毁前注销。

LocalBroadcastManager实现原理:是应用内广播,利用Handler实现。
1.使用了单例模式,并且将外部传入的Context转换成了Application的Context,避免造成内存泄露。
2.在构造方法中创建了Handler,实质是通过Handler进行发送和接受消息的。
3.创建Handler时,传入了主线程的Looper,说明这个Handler是在主线程创建的,即广播接收者是在主线程接收消息的,所以不能在onReceiver()中做耗时操作。
注意:对于LocalBroadcastManager发送的广播,只能通过LocalBroadcastManager动态注册,不能静态注册。

特别注意:
1.如果BroadcastReceiver在onReceiver()方法中在10秒内没有执行完成,会造成ANR异常。
2.对于不同注册方式的广播接收者回调方法onReceive()返回的Context是不一样的。
静态注册:context为ReceiverRestrictedContext。
动态注册:context为Activity的Context。
LocalBroadcastManager的动态注册:context为Application的Context。

发送广播有sendBroadcast普通广播 sendOrderedBroadcast有序广播 本地广播
广播的注册方式有动态代码registerReceiver注册 和静态Manifest清单文件中注册
静态注册的广播接收者一经安装就常驻在系统之中,不需要重新启动唤醒接收者
动态注册的广播接收者随着应用的生命周期,由registerReceiver开始监听,由unregisterReceiver撤销监听,如果应用退出后,没有撤销已经注册的接收者应用应用将会报错。
本地广播
本地广播只能够在应用程序的内部进行传递 解决了广播安全性的问题 本地广播只能通过动态方式注册