Broadcast 问题大盘点

qiang.zhang大约 3 分钟

Broadcast 问题大盘点

  1. 广播内部实现?

自定义广播接收者 BroadcastReceiver,并复写 onRecvice();

通过 Binder 机制向 AMS(Activity Manager Service) 注册广播;

通过 Binder 机制向 AMS(Activity Manager Service) 发送广播。

AMS 查找符合相应条件(IntentFilter/Permission等)的BroadcastReceiver,将广播发送到BroadcastReceiver 所在的消息循环队列中。

BroadcastReceiver 所在消息队列拿到此广播后,回调它的 onReceive() 方法。

  1. AMS 是什么?

AMS(Activity Manager Service):是贯穿Android系统组件的核心服务,负责启动四大组件启动切换调度。

  1. 本地广播 LocalBroadcastManager
  • 背景:Android中的广播可以跨App直接通信(exported对于有intent-filter情况下默认值为true)

  • 冲突: 其他App针对性发出与当前App intent-filter相匹配的广播,由此导致当前App不断接收广播并处理; 其他App注册与当前App一致的intent-filter用于接收广播,获取广播具体信息(即会出现安全性 & 效率性的问题)。

  • 解决方案:使用App应用内广播(Local Broadcast)

App应用内广播可理解为一种局部广播,广播的发送者和接收者都同属于一个App。 相比于全局广播(普通广播),App应用内广播优势体现在:安全性高 & 效率高;

特点:

  • 发送的广播只能够在自己 App 的内部传递,不会泄露给其他 App,确保隐私数据不会泄露;
  • 广播接收器只能接收来自本 App 发出的广播;
  • 其他App也无法向你的App发送该广播,不用担心其他App会来搞破坏;
  • 比系统的全局广播更加高效。

内部实现原理:

LocalBroadcastManager 高效的原因主要因为它内部是通过Handler实现的,它的sendBroadcast()方法是通过handler()发送一个Message。

相比系统广播是通过Binder实现的,本地广播会更加高效。别人应用无法向自己的App发送广播,而自己App发送的广播也不会离开自己的App。

LocalBroadcastManager 内部协作主要是靠两个Map集合:mReceivers和mActions,当然还有一个List集合mPendingBroadcasts,主要是存储待接收的广播对象。

  1. 全局广播的缺点?
  • App被反编译获得Action后,会被植入广告、数据泄露。
  1. BroadcastReceiver 和 LocalBroadcastReceiver 区别?
  • BroadcastReceiver 是跨应用广播,利用Binder机制实现。
  • LocalBroadcastReceiver 是应用内广播,利用Handler实现,利用了IntentFilter的match功能,提供消息的发布与接收功能,实现应用内通信,效率比较高。
  1. Broadcast Receiver能在onReceive中执行耗时任务吗?

BroadcastReceiver 在 10 秒内没有执行完毕,Android 会认为该程序无响应ANR,所以在 onReceive 通常是不能开启线程的,一般是通过 service 或者 IntentService 来处理。

  1. BroadCastReceiver 的生命周期
  • 广播接收者的生命周期非常短暂的,在接收到广播的时候创建,onReceive()方法结束之后销毁;
  • 广播接收者中不要做一些耗时的工作,否则会弹出 Application No Response应用无响应对话框;
  • 最好也不要在广播接收者中创建子线程做耗时的工作,因为广播接收者被销毁后进程就成为了空进程,很容易被系统杀掉;
  • 耗时的较长的工作最好放在服务中完成;
  1. 广播传输的数据是否有限制,是多少,为什么要限制?
  • Broadcast广播通过Intent来传输数据,而Intent的数据大小限制为小于1MB,如果大于等于1MB都会出现异常。

  • Intent携带信息的大小其实是受Binder限制,Binder传递缓存有一个限定大小,通常是1Mb。但同一个进程中所有的传输共享缓存空间。多个地方在进行传输时,即使它们各自传输的数据不超出大小限制,TransactionTooLargeException异常也可能会被抛出。

Loading...