Broadcast Receiver详解
- 广播
- 广播定义
与应用程序之间传输信息的机制,类似JAVA当中的观察者模式,当被观察者发生变化时会通知观察者做相应的变化。
定义:在android中,broadcast是一种广泛运用的在应用程序之间传输信息的机制,Android中我们要发送的广播内容是一个intent,这个intent中可以携带我们要传送的数据。
在广播中和发送action相同都可以接受这个广播,广播接受者可以有一个通知的作用,通过广播接受者来接受service发过来的数据再发给activity来更新UI
- 广播的场景
- 同一app具有多个进程的不通组件的消息通信
两个进程之间的通信可以用到广播
- 不同app之前的组件消息通信
比如一个公司多个app之间的消息推广
- 广播的种类
- Normal Broadcast:sendBroadcast
普通广播
- System Broadcast:sendOrderedBroadcast
有序广播,可以算是一种系统广播
- Local Broadcast:只在自身APP内传播
本地广播
- 实现广播-receiver
- 静态注册:注册完成就一直运行
直接把广播接受者写在Manifest.xml中,它所依赖的Activity销毁了仍然可以接受广播,即使把进程杀死仍然可以接受到广播,跟动态注册不是很灵活。
- 动态注册:跟随activity的生命周期
一定要在onDestroy中一定要执行unregisterReceiver(receiver) ,否则会引起内存泄露
动态注册与静态注册区别:
- 动态注册使用代码来实现,静态注册是在xml中把广播接受者写在里面
- 动态注册受activity生命周期的影响,静态注册不受activity生命周期的影响,即使app已经被销毁
- 广播实现机制
- 自定义广播接受者BroadcastReceiver,并复写onReceive()方法;
- 广播通过Binder机制向AMS(Activity Manager Service)进行注册;
- 广播发送者通过Binder机制向AMS发送广播;
- AMS查找符合相应条件(IntentFilter/Permission等)的BroadcastReceiver,将广播发送到BroadcastReceiver(一般情况下是Activity)相应的消息循环队列中;
- 消息循环执行拿到此广播,回调BroadcastReceiver中的onReceive()方法。
Binder机制是Android进程间通信的一个核心,整体结构是客户端服务端结构C/S,客户端进程可以获取到服务端进程的代理,通过代理来读取数据来完成进程间的数据通信。
AMS其实发送广播的一个枢纽
- LocalBroadcastManager详解
- 使用它发送的广播将只在自身app内传播,因此不必担心泄露隐私数据
- 其它App无法对你的App发送该广播,因为你的app根本就不可能接受到非自身应用发送的该广播,因此不必担心有安全漏洞可以利用
- 比系统的全局广播更加高效
安全漏洞:别人反编译你的apk后知道了你的action,第三方应用可以发送与该action相同的广播,而你的应用也能接收到,这个时候就可以拿这个广播来做很多事情。比如:分享一个链接让你跳转过去,植入广告的形式;当你使用广播来传送数据的时候,别的应用也能接收到
LocalBroadcastManager内部实现单列模式
三个主要方法:mReceivers,mActions,mPendingBroadcasts
final HashMap<BroadcastReceiver,ArrayList<IntentFilter>> mReceivers
广播接受器可以接收不通action的广播,一个BroadcastReceiver和action是一一对应的。
final HashMap<String,ArrayList<ReceiverRecord>> mActions
Action所对应的receiverRecord
final ArrayList<BroadcastRecord> mPendingBroadcasts
用来存储发送和广播的action匹配的receiverRecord集合,存储了一个广播接收器的存储器
registerReceiver():注册广播
- add(filter)为传入广播添加器添加指定的IntentFilter过滤规则
- add(entry)把IntentFilter里的action分别建立了receiver映射,通过广播接收器来接收action的广播
unregisterReceiver():删除广播
- 把mReceivers广播接收器删除
- 把mActions表中的广播器移除
sendBroadcast():发送广播
1.通过mPendingBroadcasts
- LocalBroadcastManager搞笑的原因主要是因为它内部是通过Handler实现的,它的sendBroadcast()方法并非和我们平时所用的一样,它的sendBroadcast()方法其实是通过Handler发送一个Message实现的
- 既然是它内部是通过Handler来实现广播的发送的,那么相比于系统广播通过Binder实现那肯定是更高效了,同时使用Handler来实现,别的应用无法向我们的应用发送该广播,而我们应用内发送的广播也不会离开我们的应用
- LocalBroadcastManager内部协作主要是靠这两个MAP集合:mReceivers和mActions,当然还有一个List集合mPendingBroadcasts,这个主要就是存储待接收的广播对象