一、作用
BroadcastReceiver是一个全局监听器,实现了系统中不同组件之间的通信。OnXxxListener只是程序级别的监听器,运行在同一进程中。BroadcastReceiver属于系统级别的监听器,拥有自己的进程,即使app没有运行,只要存在与之匹配的Intent被广播出来,BroadcastReceiver就会被激发。
应用场景:
1、Android不同组件间的通信(含 :应用内 、 不同应用之间)
2、多线程通信
3、与 Android 系统在某种状态改变时会发送系统广播,如:开机、电话呼入时、网络可用时
二、BroadcastReceiver的分类
1、普通广播
1)、同一时刻被所有接收者接收到,消息传递的效率比较高
2)、缺点:接收者不能将处理结果传递给下一个接收者,并且无法终止广播Intent的传播
3)、发送普通广播使用sendBroadcast()
2、有序广播
1)、接收者按预先声明的优先级依次接收广播。如:A的级别高于B,B的级别高于C,那么,广播先传给A,再传给B,最后传给C。A得到广播后,可以往广播里存入数据,当广播传给B时,B可以从广播中得到A存入的数据。
2)、优先级声明在<intent-filter/>元素的android:priority属性中,数越大优先级别越高,取值范围为-1000~1000。代码中定义调用IntentFilter对象的setPriority()进行设置,如:intentFilter.setPriority(int)。静态注册xml中代码如下:
<receiver android:name=".receiver.OrderedBroadcast1">
<intent-filter android:priority="-1">
<action android:name="com.demo.receiver.orderreceiver"></action>
</intent-filter>
</receiver>
3)、发送有序广播使用sendOrderedBroadcast(intent)。注意:有序广播在xml中注册时要指定相同的action,intent中指定action,这样就能启动这些Receiver。
4)、接受者将处理结果传给下一个接受者
优先接收到广播的接收者可以通过setResultExtras(Bundle)方法将处理结果存入广播中,然后传递给下一个接收者。下一个接收者通过Bundle bundle = getResultExtra(true)获取上一个接收者存入的数据。
public void onReceive(Context context, Intent intent) {
Bundle bundle = new Bundle();
bundle.putString("msg", "OrderedBroadcast1设置的数据");
setResultExtras(bundle);
}
注意:在onReceive中更改启动者在Intent中传入的数据没有效果,下一个Receive收到intent中的数据并没有改变,具体原因未知。
5)、如何取消广播?
abortBroadcast(); 低优先级的接收者将收不到广播。
三、定义BroadcastReceiver
1、编写继承BroadcastReceiver的子类
实现onReceiver方法
2、注册
系统通过action找到对应的BroadcastReceiver
1)、静态注册
在AndroidManifest.xml中配置
<receiver android:name=".normalbroadcast.MyStaticBroadcastReceiver">
<intent-filter>
<action android:name="com.receiver.mystaticreceiver"/>
</intent-filter>
</receiver>
2)、动态注册
注意:对于动态广播,有注册就必然得有注销,否则会导致内存泄露
通过代码注册 :
DynamicRegisterReceiver dynamicRegisterReceiver = new DynamicRegisterReceiver();
IntentFilter intentFilter = new IntentFilter("com.demo.receive.register");
registerReceiver(dynamicRegisterReceiver, intentFilter);
发送动态注册广播:
intent = new Intent();
intent.setAction("com.demo.receive.register");
sendBroadcast(intent);
解除动态注册的广播:
unregisterReceiver(dynamicRegisterReceiver);
dynamicRegisterReceiver就是注册时的dynamicRegisterReceiver
3、注意
1)、onReceive()必须在10s内完成,否则会报ANR。所以有耗时操作应该启动Service完成
2)、注册广播的activity关闭后广播也失效,接收不到广播数据
四、发送广播
1、发送普通广播
sendBroadcast()
2、发送有序广播
sendOrderedBroadcast()
五、注意事项
1、BroadcastReceiver的生命周期
如果一个广播处理完onReceive 那么系统将认定此对象将不再是一个活动的对象,也就会finished掉它。
2、BroadcastReceiver生命周期很短
如果需要在onReceiver完成一些耗时操作,应该考虑在Service中开启一个新线程处理耗时操作,不应该在BroadcastReceiver中开启一个新的线程。因为BroadcastReceiver生命周期很短,在执行完onReceiver以后BroadcastReceiver就结束,如果开启一个新的线程,可能出现BroadcastRecevier退出以后线程还在,而如果BroadcastReceiver所在的进程结束了,该线程就会被标记为一个空线程,根据Android的内存管理策略,在系统内存紧张的时候,会按照优先级,结束优先级低的线程,而空线程无异是优先级最低的,这样就可能导致BroadcastReceiver启动的子线程不能执行完成。
六、BroadcastReceiver权限设置
详见博客Android权限管理