BroadcastReceiver也就是“广播接收者”的意思,顾名思义,它就是用来接收来自系统和应用中的广播
在Android系统中,广播体现在方方面面,例如当开机完成后系统会产生一条广播,接收到这条广播就能实现开机启动服务的功能;当网络状态改变时 系统会产生一条广播,接收到这条广播就能及时地做出提示和保存数据等操作;当电池电量改变时,系统会产生一条广播,接收到这条广播就能在电量低时告知用户 及时保存进度,等等。
Android中的广播机制设计的非常出色,很多事情原本需要开发者亲自操作的,现在只需等待广播告知自己就可以了,大大减少了开发的工作量和开发周期。而作为应用开发者,就需要数练掌握Android系统提供的一个开发利器,那就是BroadcastReceiver。
首先需要简单介绍一下广播接收器,主要可分为两种类型,标准广播和有序广播。
标准广播(Normal broadcasts)是一种完全异步执行的广播,在广播发出之后,所有的广播接收器几乎同时收到这一条广播消息,因此它们之间没有任何先后顺序可言。这种广播效率会比较高,但同时也意味着它是无法被截断的。
有序广播(Ordered broadcasts)是一种同步执行的广播,在广播发出之后,同一时刻只会有一个广播接收器能够收到这条广播消息,当这个广播接收器中的逻辑执行完毕后,广播才会继续传递。所以此时的广播接收器是有先后顺序的,优先级高的广播接收器可以先收到广播消息,并且前面的广播接收器还可以截断正在传递的广播,这样后面的广播接收器就无法收到广播消息了。
我们先用一个简单的demo来演示一下广播接收器的使用
1.需要写一个自己定义的接收器,它是BroadcastReceiver的子类,在其中重写onReceiver方法,在其中做逻辑操作(一般会需要使用intent中传来的内容)
2.指定广播地址,并进行注册。(这里分为了静态注册,就是在AndroidManifest.xml文件中配置,和动态注册,就是在代码中使用代码写)
3.当该Activity或Service被注销时,记得要解除注册,一般就是写在onDestory()中写入unregisterReceiver(自己写的子类)
来看看代码:
1.自己定义的接收器
public class BootCompleteReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
Toast.makeText(context,"Boot Complete",Toast.LENGTH_LONG).show();
}
}
2.指定广播地址,并进行注册。
静态注册
这种方式的注册是 常驻型的,也就是说当应用关闭后,如果有广播信息传来,BootCompleteReceiver也会被系统调用而自动运行。
receiver
android
:name=
".BootCompleteReceiver">
<
intent-filter>
<
action
android
:name=
"android.intent.action.BOOT_COMPLETED"/>
</
intent-filter>
</receiver>
配置了以上信息之后,只要是android.intent.action.BOOT_COMPLETED这个地址的广播,BootCompleteReceiver都能够接收的到。
动态注册
不是常驻型的,也就是说广播会跟随程序的生命周期。 动态注册需要在代码中动态的指定广播地址并注册,通常我们是在Activity或Service注册一个广播。
intentFilter =
new IntentFilter();
intentFilter.addAction(
"android.net.conn.CONNECTIVITY_CHANGE");
networkChangeReceiver =
new NetworkChangeReceiver();
registerReceiver(networkChangeReceiver,intentFilter);
注意,registerReceiver是android.content.ContextWrapper类中的方法,Activity和Service都继承了ContextWrapper,所以可以直接调用。
我们在Activity或Service中注册了一个BroadcastReceiver,当这个Activity或Service被销毁时如果没有解除注册,系统会报一个异常,提示我们是否忘记解除注册了。
3.当该Activity或Service被注销时记得解除注册,上面也已经提到了。
protected void onDestroy(){
super.onDestroy();
unregisterReceiver(
networkChangeReceiver);
}
android.net.conn.CONNECTIVITY_CHANGE(这个是android内部网络状态发生改变时发送的广播) 或者是来自 android.intent.action.BOOT_COMPLETED(这个是重启之后开机自启动,唯有静态注册才能完成)
写在这里,做完以上工作后,android系统为了保证应用程序的安全性做了规定,如果程序需要访问系统的一些关键性信息,必须在配置文件中进行声明权限才可以,否则程序将直接崩溃。
权限声明在AndroidManifest.xml文件中
uses-permission
android
:name=
"android.permission.ACCESS_NETWORK_STATE"/> 获取网络状态权限
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/> 获取重启自启动权限
关于权限的内容可以参考网上的一些资料,也可以参考链接中的:
以上,我们就介绍了广播接收器的基本工作方式,并且介绍了两种注册方式,静态可实现开机启动,动态就更加灵活。
有一点需要 注意:不要在onReceiver()方法中添加过多的逻辑或者进行任何的耗时操作,因为在广播接收器中是不允许开启线程的,当onReceiver()方法运行了较长时间而没有结束时,程序就会报错。 因此广播接收器更多的是扮演一种打开程序其他组件的角色,比如创建一条状态栏通知,或者启动一个服务等。
说了这么多还没讲到标准广播 和 有序广播
其实上述的demo就是一个标准广播,记住一点就好,标准广播可以同时接受到广播信息,无法被截断,效率较高。
而有序广播,在接收器这方面要做的一个动作是设置广播接收器的优先级。关于优先级的问题可以参考网上一些博客。或是这个博客:
先来看看配置文件怎么写的
• <receiver android:name=".FirstReceiver">
• <intent-filter android:priority="1000">
• <action android:name="android.intent.action.MY_BROADCAST"/>
• <category android:name="android.intent.category.DEFAULT" />
• </intent-filter>
• </receiver>
• <receiver android:name=".SecondReceiver">
• <intent-filter android:priority="999">
• <action android:name="android.intent.action.MY_BROADCAST"/>
• <category android:name="android.intent.category.DEFAULT" />
• </intent-filter>
• </receiver>
• <receiver android:name=".ThirdReceiver">
• <intent-filter android:priority="998">
• <action android:name="android.intent.action.MY_BROADCAST"/>
• <category android:name="android.intent.category.DEFAULT" />
• </intent-filter>
• </receiver>
abortBroadcast();方法
总体来说:对于接收同一个广播,在相同优先级的情况下,动态注册优先级别高于静态注册。在动态注册中,最早动态注册优先级别最高;在静态注册中,最早安装的程序,静态注册优先级别最高(安装APK会解析manifest.xml,把其加入队列)。
就介绍到这里吧。
还有一个本地广播