一、简介:
BroadcastReceiver是Android系统四大组件之一,其实质是一个全局监听器。为什么说它是Android开发利器呢?BroadcastReceiver不仅可以接收系统的广播消息,也可以接收用户自定义的广播消息。它没有界面,你几乎看不出它的存在(它比Service隐藏的还要深),但是它一直默默地工作,当接收到指定的广播消息后,它就开始活跃起来了,它可以启动Activity和Service,也可以操作数据库和文件,甚至是连接网络,只要不是太耗时的任务,你都可以交给它来处理。
Android系统大量运用了广播机制,例如系统开机、收到短信、电池电量变化、屏幕锁屏等等,可以参考http://www.eoeandroid.com/thread-203771-1-1.html。由此可见,利用BroadcastReceiver可以做很多事情。下面就介绍一下如何利用BroadcastReceiver编程。
二、编程步骤
1. 继承BroadcastReceiver基类,实现自己的Receiver类
首先需要继承系统提供BroadcastReceiver类,重写其onReceive方法。onReceive方法的原型为:
public void onReceive(Context context, Intent intent),它包含两个参数:
context对象代表BroadReceiver运行的上下文环境,可以通过它启动Activity、Service或者发送广播,也可以将它作为构造Intent的参数。
Intent对象中包含了广播发送者希望希望BroadcastReceiver知道的消息,包括广播的类型(Action)以及其他消息,BroadcastReceiver一般都是根据Intent中包含的Action来判断这个广播是不是发给自己的。
当BroadcastReceiver接收到指定的广播之后就会触发onReceive方法,因此我们可以把自己的业务放在onReceive方法中实现。不过需要注意的是,这个方法里不能执行耗时任务,具体原因后面会解释。
代码示例:public class BootReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
// 处理具体的业务
// 这里启动一个service
if(intent.getAction().equals("android.intent.action.BOOT_COMPLETED"))
{
context.startService(new Intent(context, ReminderService.class));
}
}
}
2. 注册BroadcastReceiver
BroadcastReceiver需要注册才能生效。注册方式有两种:
一种是在程序中用代码进行注册,代码如下:
IntentFilter filter=new IntentFilter();
// 系统开机事件的广播
// 这里添加的Action是不会被过滤的
filter.addAction("android.intent.action.BOOT_COMPLETED");
BootReceiver receiver=new BootReceiver();
// 注册Receiver
registerReceiver(receiver, filter);
通过这种方式注册的BroadcastReceiver只有在程序的主进程活动的时候才会起作用,如果程序进程被杀死,BroadcastReceiver也就失效了。这种方式适合程序内部组件之间的通信,例如通知ListView刷新。
另一种是在AndroidManifest.Xml文件中注册,代码如下:
<receiver android:name="com.fx.theday.receiver.BootReceiver" >
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
通过这种方式注册的BroadcastReceiver即使在程序主进程停止的状态下也能生效,因此这种方式适合接收系统级的广播,如监听开机事件。
这两种方法中都用到了IntentFilter,顾名思义,IntentFilter是用来过滤Intent的,只有IntentFilter指定的Intent才能够被BroadcastReceiver接收到。
如果只是接收系统广播,那么到这里BroadcastReceiver就已经准备就绪了,可以静静地等待广播的到来了;如果是接收用户自己发送的广播,那么请看第3步。
3. 在需要的地方发送广播
在程序中发送广播十分简单,只要调用Context的sendBroadCast(Intent intent)方法即可。该方法包含一个Intent参数,前面已经说过,这个参数里装的是广播发送者发送给BroadcastReceiver的消息,通常只需要为Intent设置一个Action就够了,这个Action就可以看成是广播的“名字”,BroadcastReceiver可以通过这个“名字”来识别这个广播是不是发送给自己的。发送广播的代码如下: Button sendBroadCast=new Button(this);
sendBroadCast.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
Intent intent=new Intent();
// 这里应该使用用户自己定义的Action
intent.setAction("android.intent.action.BOOT_COMPLETED");
sendBroadcast(intent);
}
});
这样发送广播和接收广播的代码就完成了。
三、LocalBroadcastManager类
LocalBroadcastManager类是Android Support包提供了一个工具,是用来在同一个应用内的不同组件间发送Broadcast的。
使用LocalBroadcastManager有如下好处:
- 发送的广播只会在自己App内传播,不会泄露给其他App,确保隐私数据不会泄露
- 其他App也无法向你的App发送该广播,不用担心其他App会来搞破坏
- 比系统全局广播更加高效
其使用方式和BroadcastReceiver类似,具体可以参考:http://blog.chengyunfeng.com/?p=498
四、总结
BroadcastReceiver的使用并不复杂,灵活使用BroadcastReceiver可以方便地实现组件与组件之间的通信。但是在使用BroadcastReceiver的时候需要注意一些问题:
1. BroadcastReceiver短暂的生命周期
当onReceive方法执行完返回之后BroadcastReceiver对象的生命周期就结束了。
2. 不要再onReceive方法中执行耗时任务
因为该方法通常会在程序的主线程中被调用,如果执行任务时间过长(官方说法是不能超过10s)会阻塞主线程,导致应用程序无响应(ANR)。
3. 需要执行耗时任务怎么办
如果我们需要执行耗时任务,应当考虑在onReceive方法中先启动一个Service,然后在Service中启动新线程来完成任务,而不应该直接在onReceive启动新线程,因为BroadcastReceiver的生命周期很短,当BroadcastReceiver生命周期结束以后,它所启动的线程随时会被Java虚拟机终止,其结果可能就是任务还没完成,线程已经结束了。