广播的种类
Android 中的广播主要可以分为两种类型,标准广播和有序广播。
- 标准广播:是一种完全异步执行的广播,在广播发出之后,所有的广播接收器机会都会在同一时间接收到这条广播消息,效率高同时又无法被截断
- 有序广播:是一种同步执行的广播,广播发出后,同一时刻只会有一个广播接收器能够收到这条广播消息,当这个广播接收器中的逻辑执行完毕后,广播才会继续传递,所以这种类型的广播是有先后顺序的,优先级高广播接收器就可以先接收到广播消息,并且前面的广播接收器还可以截断正在传递的广播,这样后面的广播接收器就无法收到广播消息了。
广播的使用
首先要自定义一个广播接收器,继承BroadcastReceiver,然后复写onReceive() 方法,像这样:
public class MyReceiver extends BroadcastReceiver {
public static final String ACTION= "action";
@Override
public void onReceive(Context context, Intent intent) {
// TODO: This method is called when the BroadcastReceiver is receiving
//接收广播后的一些逻辑,这里注意下 onReceive方法是自动调用的
Log.d("MyReceiver", "收到广播了");
}
}
其次,就要进行广播的注册,注册主要有两种形式:
- 静态注册
- 动态注册
静态注册:在AndroidManifest.xml中添加注册
<receiver
android:name=".activity.fourComponents.MyReceiver">
<intent-filter>
<action android:name="myReceiver" />
</intent-filter>
</receiver>
当App启动的时候,会自动将MyReceiver这个接收器注册在系统当中,当收到相应的广播的时候就会自动调用MyReceiver 中的onReceive() 方法。
动态注册:尽量在onResume() 和 onPause()中进行广播的注册和销毁
private MyReceiver mMyReceiver;
if (mMyReceiver == null) {
// 实例化BroadcastReceiver子类 & IntentFilter
mMyReceiver = new MyReceiver();
IntentFilter intentFilter = new IntentFilter();
//设置接收广播的类型
intentFilter.addAction("myReceiver");
//动态注册:调用Context的registerReceiver()方法
registerReceiver(mMyReceiver, intentFilter);
}
最后不能忘记要销毁动态广播
//广播动态销毁
unregisterReceiver(mMyReceiver);
不管是静态注册还是动态注册,他们的共同点:
- 自动回调onReceive() 方法
- 广播接收器运行在UI线程
所以在广播中不能做耗时操作,否则就会导致ANR
静态注册和动态注册的区别
静态注册和动态注册的区别主要从这三个方面来看:
- 使用方式
- 特点
- 应用场景
使用方式
动态注册:在代码中调用Context.registerReceiver
静态注册:在AndroidManifest.xml通过标签声明
特点
动态注册:跟随组件的生命周期变化
静态注册:常驻进程中,不受组件生命周期影响(即使应用程序关闭,如果有广播发送,程序依然会被系统唤醒调用)
应用场景
静态注册:需要时刻监听广播(比如在性能优化时,计算每隔一段时间的网络访问量)
动态注册:需要在特定时刻接受广播(可根据业务场景选择)
广播接收器更多的是扮演一种打开程序其他组件的角色,例如创建一条状态栏通知,或者启动一个服务等。
广播的原理
Android中的广播使用了观察者模式,角色分配:
- 消息订阅者(广播接受者)
- 消息发布者(广播发布者)
- 消息中心(Activity Manager Service,即AMS)
原理简述:
- 广播接收者:通过Binder 机制在 AMS 注册
- 广播发送者:通过Binder 机制向 AMS 发送广播
- AMS 根据广播发送者要求,在已注册列表中,寻找合适的广播接受者
- AMS 将广播发送到合适的广播接收者相应的消息循环队列中