android开发之路02(浅谈BroadcastReceiver),broadcastreceiver
一.BroadcastReceiver (广播接收者)的作用是用来接收来自系统和应用中的广播。应用如下:
1.开机完成后系统会产生一条广播----->接收到这条广播就能实现开机启动服务的功能;
2.网络状态改变时系统会产生一条广播,接收到这条广播就能及时地做出提示和保存数据等操作;
当电池电量改变时,系统会产生一条广播,接收到这条广播就能在电量低时告知用户及时保存进度;
Android中的广播机制设计的非常出色,大大减少了开发的工作量和开发周期。
二.静态注册广播接收者和动态注册广播接收者
①创建BroadcastReceiver对象,让其继承android.content.BroadcastReceiver这个类,并实现其onReceive方法。
例如:public class MyReceiver extends BroadcastReceiver{
@Override
public void onReceive(Context context, Intent intent) {
//获取随广播而来的Intent中的数据
String msg=intent.getStringExtra("msg");
//在界面输出提示信息
Toast.makeText(context, msg, Toast.LENGTH_LONG).show();
}
}
在创建完我们的BroadcastReceiver之后,还不能够使它进入工作状态,我们需要为它注册一个指定的广播地址。
②为BroadcastReceiver注册广播地址之静态注册:静态注册是在AndroidManifest.xml文件中配置的,如:
<receiver android:name=".MyReceiver">
<intent-filter>
<action android:name="android.intent.action.MY_BROADCAST"/>
<category android:name="android.intent.category.DEFAULT"/>
</intent-filter>
</receiver>
配置了以上信息之后,只要是android.intent.action.MY_BROADCAST这个地址的广播,MyReceiver都能够接收的到。注意,这种方式的注册是常驻型的,也就是说当应用关闭后,如果有广播信息传来,MyReceiver也会被系统调用而自动运行。
③为BroadcastReceiver注册广播地址之动态注册: 动态注册需要在代码中动态的指定广播地址并注册,通常我们是在Activity或Service注册一个广播,例如:
public class MainActivity extends Activity {
private MyReceiver myReceiver;
IntentFilter intentFilter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
myReceiver=new MyReceiver();
intentFilter=new IntentFilter();
intentFilter.addAction("android.intent.action.MY_BROADCAST");
//registerReceiver是android.content.ContextWrapper类中的方法,
//Activity和Service都继承了ContextWrapper,所以可以直接调用
registerReceiver(myReceiver, intentFilter);
}
}
在实际应用中,我们在Activity或Service中注册了一个BroadcastReceiver,当这个Activity或Service被销毁时如果没有解除注册,系统会报一个异常,提示我们是否忘记解除注册了。所以,记得在加上:
@Override
protected void onDestroy() {
super.onDestroy();
unregisterReceiver(myReceiver);
}
就可以解决问题了。注意,这种注册方式与静态注册相反,不是常驻型的,也就是说广播会跟随程序的生命周期。
④发送广播,代码如下:
public void send(View v){
Intent intent=new Intent();
intent.putExtra("msg", "你好,接收者");
//sendBroadcast也是android.content.ContextWrapper类中的方法,
//它可以将一个指定地址和参数信息的Intent对象以广播的形式发送出去
sendBroadcast(intent);
}
⑤在布局文件中声明一个button控件:
<Button
android:id="@+id/button1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="点我发送广播"/>
MainActivity中获取button控件的对象并注册监听器,代码如下:
private Button button1;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
button1=(Button) findViewById(R.id.button1);
button1.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
send(v);
}
});
}
三.普通广播(Normal Broadcast)和有序广播(Ordered Broadcast)
普通广播对于多个接收者来说是完全异步的,通常每个接收者都无需等待即可以接收到广播,接收者相互之间不会有影响。对于这种广播,接收者无法终止广播,即无法阻止其他接收者的接收动作。我们只需要通过创建几个不同的广播接收者并声明即可,这里不做演示。
有序广播比较特殊,它每次只发送到优先级较高的接收者那里,然后由优先级高的接受者再传播到优先级低的接收者那里,优先级高的接收者有能力终止这个广播。
实例如下:
FirstReceiver.java
public class FirstReceiver extends BroadcastReceiver{
@Override
public void onReceive(Context context, Intent intent) {
String msg=intent.getStringExtra("msg");
Toast.makeText(context, msg, Toast.LENGTH_LONG).show();
Bundle bundle=new Bundle();
/**
* 使用setResultExtras方法将一个Bundle对象设置为结果集对象,传递到下一个接收者那里,
* 这样一来,优先级低的接收者可以用getResultExtras获取到最新的经过处理的信息集合
*/
bundle.putString("msg", "FirstReceiver:"+msg);
setResultExtras(bundle);
}
}
SecondReceiver
public class SecondReceiver extends BroadcastReceiver{
@Override
public void onReceive(Context context, Intent intent) {
String msg=getResultExtras(true).getString("msg");
Toast.makeText(context, msg, Toast.LENGTH_LONG).show();
Bundle bundle=new Bundle();
bundle.putString("msg", msg);
setResultExtras(bundle);
}
}
ThirdReceiver.java
public class ThirdReceiver extends BroadcastReceiver{
@Override
public void onReceive(Context context, Intent intent) {
String msg=getResultExtras(true).getString("msg");
Toast.makeText(