应用程序的运行环境不是一成不变的,SD卡的插拔、电池电量低等事件会影响应用程序的运行。为了能够正确地做出相应,应用程序必须能够监听此类事件,并做出正确地处理。在android系统中,BroadcastReceiver就是满足这样要求的一个组件。
java.lang.Object
|-- android.content.BroadcastReceiver
与其它三大组件不同的是,BroadcastReceiver并不继承ComponentCallbacks,这是由其作用而决定的。
BroadcastReceiver,正如其名字所示,用于接收程序(包括用户开发的程序和系统内建程序)所发出的Broadcast Intent。与Activity、Service有生命周期不同,BroadcastReceiver本质上只是一个系统级的监听器。BroadcastReceiver没有界面显示,却可以通过AndroidManifest.xml或在代码中进行注册,以监听应用程序感兴趣的事件。当应用程序发出一个Broadcast Intent之后,所有匹配该Intent的BroadcastReceiver都有可能被启动。
与之前提到的各类on***Listener不同的是,on***Listener只是程序级的监听器,这些监听器运行在指定程序所在的进程中,当程序退出时,这些监听器也就随之关闭了。但BroadcastReceiver属于系统级的监听器,它拥有自己的进程,只要存在与之匹配的Intent被广播出来,BroadcastReceiver总会被激发。当广播事件到来时,BroadcastReceiver的onReceive()方法会被调用。
BroadcastReceiver是一个抽象类,定义了一个抽象方法onReceive():
onReceive(Context getContext,Intent broadcastMsg);
一旦实现了BroadcastReceiver,接下来就应该指定BroadcastReceiver能匹配的Intent,有如两种方法:
- 使用代码进行指定,调用BroadcastReceiver的Context的registerReceiver(BroadcastReceiver receiver,IntentFilter filter)方法指定
- 在AndroidManifest.xml中进行配置
<receiver android:name="nku.jerry.crazyit.crazyit_23.MyReceiver" > <intent-filter> <action android:name="android.provider.Telephone.SMS_RECEIVED" /> </intent-filter> </receiver>
每次系统Broadcast事件发生后,系统就会创建对应的BroadcastReceiver的实例,并自动触发它的onReceive()方法,onReceive()方法执行完成后,BroadcastReceiver的实例就会被销毁。如果BroadcastReceiver的onReceive()方法不能在10秒内执行完成,android会认为该程序无响应。所以不要在BroadcastReceiver的onReceive()方法里执行一些耗时操作,否则会出现ANR(Application Not Response)对话框。
如果确实要根据Broadcast来完成一项比较耗时的操作,这可以考虑通过Intent启动一个Service来完成该操作,不应考虑使用新线程去完成耗时的操作,因为BroadcastReceiver本身的生命周期很短,可能出现的情况是子线程还没有结束,BroadcastReceiver就已经退出了。
下面以一个简单的小程序说明如何使用BroadcastReceiver接受发出的广播:
Activity程序如下,程序中使用sendBroadcast()方法来发送一条广播:
public class MainActivity extends Activity
{
//用于发送广播
Button send=null;
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
send=(Button)findViewById(R.id.send);
send.setOnClickListener(new OnClickListener()
{
@Override
public void onClick(View view)
{
Intent intent=new Intent();
intent.setAction("nku.jerry.crazyit.crazyit_23.MY_BROADCAST");
intent.putExtra("msg","this is a message.");
//send broadcast
sendBroadcast(intent);
}
});
}
}
程序中用到一个Button组件,只需在布局文件中配置即可,此处不再给出。
该程序所使用的BroadcastReceiver代码如下:
public class MyReceiver extends BroadcastReceiver
{
@Override
public void onReceive(Context context, Intent intent)
{
Toast.makeText(context, "接收到的Intent的Action为:"+intent.getAction()+
"\n消息内容是:"+intent.getStringExtra("msg"),Toast.LENGTH_LONG).show();
}
}
注意要在AndroidManifest.xml文件中进行响应配置:
<receiver
android:name="nku.jerry.crazyit.crazyit_23.MyReceiver" >
<intent-filter>
<action
android:name="nku.jerry.crazyit.crazyit_23.MY_BROADCAST" />
</intent-filter>
</receiver>
程序运行效果截图: