如有转载,请申明:
转载至 http://blog.csdn.net/qq_35064774/article/details/52578980
概述
BroadcastReceiver是安卓中四大组件之一,用于接受广播通知。常用于监听系统的事件,比如:开机、锁屏、解锁屏、电量变化、网络变化、短信收发等。有时候还有收发自定义的广播的需求。
广播注册方式
静态注册:
在AndroidManifest.xml文件中配置
<receiver android:name="com.ittianyu.broadcast.MyReceiver">
<intent-filter>
<action android:name="android.intent.action.MY_BROADCAST"/>
</intent-filter>
</receiver>
简单解析一下上面的组成部分。
receiver标签表示注册了一个广播接收者,其属性android:name="com.ittianyu.broadcast.MyReceiver"表明该广播接收者的类是com.ittianyu.broadcast.MyReceiver。
action中表示的是监听的内容。
动态注册:
在代码中注册。
ScreenStatusReceiver receiver = new ScreenStatusReceiver();
IntentFilter filter = new IntentFilter();
filter.addAction("android.intent.action.SCREEN_ON");
filter.addAction("android.intent.action.SCREEN_OFF");
registerReceiver(receiver, filter);
这里是注册了屏幕上锁和解锁的广播。
ScreenStatusReceiver 是广播接受类,留到后面介绍。
注册了广播后,记得在退出Activity时取消注册,并把接收对象置空,及时释放引用。
@Override
protected void onDestroy() {
super.onDestroy();
// 取消注册
unregisterReceiver(receiver);
receiver = null;
}
广播的接听
/**
* 广播接收类
*/
private class ScreenStatusReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
if("android.intent.action.SCREEN_ON".equals(intent.getAction())) {
tvScreenStatus.append("屏幕解锁了" + new Date().toLocaleString() + "\n");
} else if("android.intent.action.SCREEN_OFF".equals(intent.getAction())) {
tvScreenStatus.append("屏幕上锁了" + new Date().toLocaleString() + "\n");
}
}
}
要想接受到广播,我们需要一个BroadcastReceiver的实现类。如上代码,当收到注册的类型的广播时,就会回调onReceive方法,我们可以通过intent.getAction()拿到具体的广播类型。
需要注意的时,如果想在广播接收类中直接操作Activity的控件,可以定义为Activity的内部类。或者你也可以选择传递引用或者其他方式,但注意持有Activity的引用时,要格外小心及时释放,否则会导致内存泄漏。
两种注册方式之间其实是有区别的,在高版本安卓中,部分频繁发送的广播事件只能动态注册,也就是代码方式注册。比如:电量变化、锁屏、解锁等广播事件。至于这么设计,大概是考虑到在配置文件中注册,将会一直运行接收者的代码,而通过代码方式注册的,在应用退出后,就无法接收了,这样省电省资源。(个人理解,如有不对,欢迎指正)
广播分类
普通广播
普通广播的特点是,一旦广播发送,所有注册了的接收者将无特定顺序的接收到广播,接收者之间不会有相互影响。
这种类型的广播在生活中存在很多例子,比如:校园广播、街道广播、讲厅广播等。
有序广播
有序广播的特点就是接受者之间有先后顺序,权限高的先收到,并且还有修改广播内容和截断广播的权利,但在发送有序广播的时候,可以指定最终接收者,这样就可以防止中途有人截断广播。
解析来我们通过一份代码来了解一下有序广播。
// 高权限的接收者
public class BigReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
String data = getResultData();
System.out.println("收到最高指令:" + data);
setResultData("每人发500块钱");
}
}
// 中等权限的接收者
public class MiddleReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
String data = getResultData();
System.out.println("收到最高指令:" + data);
setResultData("每人发200块钱");
// 取消广播
abortBroadcast();
}
}
// 低权限的接收者
public class SmallReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
String data = getResultData();
System.out.println("收到最高指令:" + data);
System.out.println("已收到");
}
}
上面定义了三个接收者,然后我们在清单文件中配置三个接收者,并设置相应大小的权限。
<receiver
android:name=".com.ittianyu.basictest.custombroadcast.BigReceiver"
android:enabled="true"
android:exported="true">
<intent-filter android:priority="1000">
<action android:name="com.ittianyu.broadcast.order" />
</intent-filter>
</receiver>
<receiver
android:name=".com.ittianyu.basictest.custombroadcast.MiddleReceiver"
android:enabled="true"
android:exported="true">
<intent-filter android:priority="500">
<action android:name="com.ittianyu.broadcast.order" />
</intent-filter>
</receiver>
<receiver
android:name=".com.ittianyu.basictest.custombroadcast.SmallReceiver"
android:enabled="true"
android:exported="true">
<intent-filter android:priority="0">
<action android:name="com.ittianyu.broadcast.order" />
</intent-filter>
</receiver>
通过<intent-filter android:priority="xxx">就可以设置权限大小。
然后我们发送一个自定义广播,查看效果。
/**
* 发送有序广播,类似于责任链模式
*/
private void sendOrderBroadcast() {
Intent intent = new Intent();
intent.setAction("com.ittianyu.broadcast.order");
sendOrderedBroadcast(intent, null, null, null, 1, "每人发1000块钱", null);
}
控制台打印的结果如下:
收到最高指令:每人发1000块钱
收到最高指令:每人发500块钱
由于第二个接收者取消了广播,所以第三个并没有收到。
自定义广播
自定义广播的注册和系统已定义好的广播一样,这里不重复了。
发送自定义广播可以调用sendOrderedBroadcast或sendBroadcast。