BroadcastReceiver全方位解析

定义

广播接收器是Android四大组件之一,用于监听或者接收应用发出的广播消息并作出响应。

实现原理

广播接收器使用的设计模式是观察者模式,基于消息的发布、订阅事件模型。模型中有三个角色:
1 消息订阅者
2 消息发布者
3 消息中心(AMS,activity manager service)


image.png

原理描述:
1 广播接收者通过Binder机制在AMS 中注册广播
2 广播发送者通过Binder机制向AMS 发送广播
3 AMS 根据发送广播的要求在已经注册的广播中,寻找合适的广播接收者

寻找依据:IntentFilter / Permission

4 AMS 将广播发送到合适的广播接收者的消息循环队列中
5 广播接收者通过消息循环队列拿到此广播,并回调onReceive
()
特别注意:广播发送者 和 广播接收者的执行 是 异步的,发出去的广播不会关心有无接收者接收,也不确定接收者到底是何时才能接收到

具体使用

image.png
  • 自定义广播接收者
    继承自BroadcastReceiver基类,重写抽象方法onReceive(),做一些与其他组件之间的交互,比如发送Notificationn、启动service。默认情况下,广播接收器运行在UI线程,因此,onReceive方法不能执行耗时操作,否者将会导致ANR
  • 注册广播接收器
    注册的方式分为两种:静态注册和动态注册
    静态注册实例:在AndroidManifest.xml里通过 标签声明
<receiver
  //此广播接收者类是mBroadcastReceiver
  android:name=".mBroadcastReceiver" >
  //用于接收网络状态改变时发出的广播
  <intent-filter>
      <action android:name="android.net.conn.CONNECTIVITY_CHANGE" />
  </intent-filter>
</receiver>

动态注册实例:在代码中通过调用Context的registerReceiver()方法进行动态注册BroadcastReceiver

@Override
protected void onResume() {
    super.onResume();

    //实例化BroadcastReceiver子类 &  IntentFilter
    mBroadcastReceiver mBroadcastReceiver = new mBroadcastReceiver();
    IntentFilter intentFilter = new IntentFilter();

    //设置接收广播的类型
    intentFilter.addAction(android.net.conn.CONNECTIVITY_CHANGE);

    //调用Context的registerReceiver()方法进行动态注册
    registerReceiver(mBroadcastReceiver, intentFilter);
}


//注册广播后,要在相应位置记得销毁广播
//即在onPause() 中unregisterReceiver(mBroadcastReceiver)
//当此Activity实例化时,会动态将MyBroadcastReceiver注册到系统中
//当此Activity销毁时,动态注册的MyBroadcastReceiver将不再接收到相应的广播。
@Override
protected void onPause() {
    super.onPause();
    //销毁在onResume()方法中的广播
    unregisterReceiver(mBroadcastReceiver);
}
image.png
  • 广播发送者向AMS 发送广播
    广播是用”意图(Intent)“标识,定义广播的本质:定义广播所具备的“意图(Intent)”,广播发送:广播发送者将此广播的”意图“通过sendBroadcast()方法发送出去。
    广播类型:
    普通广播(Normal Broadcast)
    系统广播(System Broadcast)
    有序广播(Ordered Broadcast)
    粘性广播(Sticky Broadcast)
    App应用内广播(Local Broadcast)
    普通广播:
Intent intent = new Intent();
//对应BroadcastReceiver中intentFilter的action
intent.setAction(BROADCAST_ACTION);
//发送广播
sendBroadcast(intent);

若被注册了的广播接收者中注册时intentFilter的action与上述匹配,则会接收此广播(即进行回调onReceive())。如下mBroadcastReceiver则会接收上述广播

<receiver 
    //此广播接收者类是mBroadcastReceiver
    android:name=".mBroadcastReceiver" >
    //用于接收网络状态改变时发出的广播
    <intent-filter>
        <action android:name="BROADCAST_ACTION" />
    </intent-filter>
</receiver>

APP应用内广播

Android中的额广播可以跨进程之间通信,这样会造成安全问题,比如:
1 其他APP 不断发出与当前APP intent-filter相匹配的广播,由此导致当前App不断接收广播并处理;
2 其他App注册与当前App一致的intent-filter用于接收广播,获取广播具体信息; 即会出现安全性 & 效率性的问题。
解决方案就是:Android应用内广播的方式,App应用内广播可理解为一种局部广播,广播的发送者和接收者都同属于一个App。相比于全局广播(普通广播),App应用内广播优势体现在:安全性高 & 效率高
具体事例:

//注册应用内广播接收器
//步骤1:实例化BroadcastReceiver子类 & IntentFilter mBroadcastReceiver 
mBroadcastReceiver = new mBroadcastReceiver(); 
IntentFilter intentFilter = new IntentFilter(); 

//步骤2:实例化LocalBroadcastManager的实例
localBroadcastManager = LocalBroadcastManager.getInstance(this);

//步骤3:设置接收广播的类型 
intentFilter.addAction(android.net.conn.CONNECTIVITY_CHANGE);

//步骤4:调用LocalBroadcastManager单一实例的registerReceiver()方法进行动态注册 
localBroadcastManager.registerReceiver(mBroadcastReceiver, intentFilter);

//取消注册应用内广播接收器
localBroadcastManager.unregisterReceiver(mBroadcastReceiver);

//发送应用内广播
Intent intent = new Intent();
intent.setAction(BROADCAST_ACTION);
localBroadcastManager.sendBroadcast(intent);
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

友情链接更多精彩内容