1.BroadcastReceiver是什么?
BroadcastReceiver是Android的四大组件之一,Android系统发送的广播,在BroadcastReceiver中接收,因此BroadcastReceiver即广播接收者。广播是一种跨进程通信的方式,我们在应用程序中发出的广播,不仅在自己的应用程序中能收到,而且其他的应用程序也可以收到。广播是系统全局的,夸进程的,因此可进行组件通信,多线程通信,跨进程通讯,跨应用通信等。例如,当手机电量不足时,系统会发送一个电量不足的广播,此时,系统内的所有的应用都能接收到这个广播。当然,除了系统广播以外,我们在实际开发中也能发送自定义广播。
1.发送自定义广播
// 发送一个ACTION为MY_CUSTOM_BROADCAST的自定义广播
Intent broadcastInt = new Intent();
broadcastInt.setAction("MY_CUSTOM_BROADCAST");
sendBroadcast(broadcastInt);
在AndroidManifest.xml文件里注册广播接收者,设置ACTION为MY_CUSTOM_BROADCAST
然后实现自定义广播接收者
必须继承BroadcastReceiver并实现抽象方法onReceive
由于广播接收者默认在主线程运行,因此在onReceive中不能做耗时操作,否则会导致ANR
在onReceive既可以接收系统广播,也可以接收自定义广播。
public class MyBroadcastReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
Log.i("MyBroadcastReceiver","接收到静态注册的广播了");
}
}
最后当点击Activity的按钮发送自定义广播的时候Log打印如下
06-04 03:59:12.926 3685-3685/com.text.demo I/MyBroadcastReceiver: 接收到静态注册的广播了
2.BroadcastReceiver有几种创建方式?
BroadcastReceiver有2种注册方式
1.静态注册即在AndroidManifest.xml注册广播接收者,静态广播是通过PackageManagerService在app初始化的时候由系统注册的。
如上文提到的自定义广播,这个广播只有一个ACTION,而想实际开发中我们可以给广播接收者设置多个ACTION,并且可以在接收者的onReceive中判断ACTION。
发送自定义广播
// 发送名为MY_CUSTOM_BROADCAST的自定义广播
if(v.getId() == bt.getId()){
Intent broadcastInt = new Intent();
broadcastInt.setAction("MY_CUSTOM_BROADCAST");
sendBroadcast(broadcastInt);
}else if(v.getId() == sendBt.getId()){
Intent broadcastInt = new Intent();
broadcastInt.setAction("MY_CUSTOM_BROADCAST1");
sendBroadcast(broadcastInt);
}
接收广播
public class MyBroadcastReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
if(intent.getAction() == "MY_CUSTOM_BROADCAST"){
Log.i("MyBroadcastReceiver","接收到静态注册的广播了-MY_CUSTOM_BROADCAST");
}else if(intent.getAction() == "MY_CUSTOM_BROADCAST1"){
Log.i("MyBroadcastReceiver","接收到静态注册的广播了-MY_CUSTOM_BROADCAST1");
}
}
}
最后的输出结果
06-04 04:13:35.472 3959-3959/com.text.demo I/MyBroadcastReceiver: 接收到静态注册的广播了-MY_CUSTOM_BROADCAST
06-04 04:13:38.884 3959-3959/com.text.demo I/MyBroadcastReceiver: 接收到静态注册的广播了-MY_CUSTOM_BROADCAST1
2.动态注册即调用registerReceiver方法注册。注:在Activity中最好是在onResume方法中调用registerReceiver注册,在onDestroy方法中调用unregisterReceiver注销广播,否则会造成内存泄露。
注册,设置IntentFilter的ACTION为REGISTER_BROADCAST
@Override
protected void onResume() {
super.onResume();
// 动态注册广播
receiver = new MyBroadcastReceiver();
IntentFilter filter = new IntentFilter("REGISTER_BROADCAST");
registerReceiver(receiver,filter);
}
销毁,Activity销毁时注销广播接收者
@Override
protected void onDestroy() {
super.onDestroy();
// 销毁广播
unregisterReceiver(receiver);
}
接收广播则和静态注册一样。
3.BroadcastReceiver2种创建方式的异同?
动态注册的优点和缺点(确认下8.0是否不允许静态注册)
动态注册广播接收者相对静态注册来说要更灵活,用的时候随时注册,但需要及时销毁,否则容易造成内存泄露。
静态注册的优点和缺点
静态注册则是在APP初始化的时候就注册了,不需要注册和销毁动作,也就不存在不销毁就内存泄露的风险。
4.如何给BroadcastReceiver设置优先级?
广播分为普通广播和有序广播。普通广播为完全异步的,是可以同时被所有的广播接收者接收到,并且广播接收者收到广播后无法终止广播。而有序广播则有先后之分,且广播可以被广播接收者拦截和终止,调用abortBroadcast()方法即可终止。给有序广播设置priority属性,priority的取值范围是-1000~10000,值越大广播的优先级越高。广播接收者处理了有序广播后还可以将处理结果存入数据(可通过setResultExtras(Bundle)方法将数据存入Broadcast),当做Broadcast再传递给下一级接收者(可通过代码Bundle bundle = getResultExtras(true)获取上一级传递过来的数据)
日志结果MY_CUSTOM_BROADCAST优先级大于MY_CUSTOM_BROADCAST1,当接收到MY_CUSTOM_BROADCAST时终止广播,因此MyReceive里面就接收不到了。
代码示例
// 发送有序广播
if(v.getId() == bt.getId()){
Intent broadcastInt = new Intent();
broadcastInt.setAction("MY_CUSTOM_BROADCAST");
sendOrderedBroadcast(broadcastInt,null);
}else if(v.getId() == sendBt.getId()){
Intent broadcastInt = new Intent();
broadcastInt.setAction("MY_CUSTOM_BROADCAST1");
sendOrderedBroadcast(broadcastInt,null);
}
public class MyBroadcastReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
if(intent.getAction() == "MY_CUSTOM_BROADCAST"){
Log.i("MyBroadcastReceiver","接收到静态注册的广播了-MY_CUSTOM_BROADCAST");
abortBroadcast();
}else if(intent.getAction() == "MY_CUSTOM_BROADCAST1"){
Log.i("MyBroadcastReceiver","接收到静态注册的广播了-MY_CUSTOM_BROADCAST1");
}
}
}
public class MyReceive extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
if(intent.getAction() == "MY_CUSTOM_BROADCAST"){
Log.i("MyReceive","接收到静态注册的广播了-MY_CUSTOM_BROADCAST");
abortBroadcast();
}else if(intent.getAction() == "MY_CUSTOM_BROADCAST1"){
Log.i("MyReceive","接收到静态注册的广播了-MY_CUSTOM_BROADCAST1");
}
}
}
这是输出结果
06-04 05:16:29.570 5388-5388/com.text.demo I/MyBroadcastReceiver: 接收到静态注册的广播了-MY_CUSTOM_BROADCAST
06-04 05:16:34.379 5388-5388/com.text.demo I/MyBroadcastReceiver: 接收到静态注册的广播了-MY_CUSTOM_BROADCAST1
06-04 05:16:34.382 5388-5388/com.text.demo I/MyReceive: 接收到静态注册的广播了-MY_CUSTOM_BROADCAST1
5.有哪些常用的系统广播?
Intent.ACTION_BATTERY_LOW
//低电量广播
Intent.ACTION_BATTERY_OKAY
//充电完成广播
Intent.ACTION_BOOT_COMPLETED
//系统启动完成广播
Intent.ACTION_CAMERA_BUTTON
//拍照按钮广播
Intent.ACTION_DATE_CHANGED
//系统生日改变广播
Intent.ACTION_DEVICE_STORAGE_LOW
//系统内存不足广播
另附开发文档链接:https://developer.android.google.cn/guide/components/broadcast-exceptions
5.广播的通讯原理是什么?
1..广播的发送和接收模式,实际上是消息的发布和订阅模式,属于广义的观察者模式。
2.广播的发送为完全异步,只管发送而不管是否有接收,什么时候被接收,接收后也不需要callback。
3.广播发送者通过Binder机制发送广播到消息队列,广播接收者通过Binder机制在ActivityManagerService进行注册,当消息循环机制找到符合条件(IntentFilter/Action/Permission)的广播接收者时调用对应的广播接收者的onReceive().