今天我们来说BroadcastReceiver.这个组件本质上就是一种全局的监听器,用于监听系统全局的广播消息。所以他可以实现系统中不同组件之间的通信。他用于接收程序(包括用户开发的程序和系统内建的程序)所发出的Broadcast Intent,同样程序启动Broadcast也需要两步。
开发步骤:
1:创建需要启动的BroadcastReceiver的Intent。
2:调用Context的sendBroadcast()或sendOrderedBroadcast()方法来启动指定的BroadcastReceiver。
注:当应用程序发出一个Broadcast Intent之后,所有匹配该Intent的BroadcastReceiver都有可能被启动。
与Activity、Service具有完整的声明周期不同、BroadcastReceiver本质上只是一个系统级的监听器——他专门负责监听各程序发出的Broadcast。
与OnXxxListener不同他们只是系统级的监听器,这些监听器运行在程序所在进程,当程序退出,OnXXXListener监听器也随之关闭,但BroadcastReceiver属于系统级他拥有自己的进程,只要存在与之匹配的Intent广播出来,BroadcastReceiver都会被激发。
因为BroadcastReceiver本质上还是一个监听器所以只要重写他的onReceive(Context context,Intent intent)方法就行了。
下面有两种方式注册BroadcastReceiver:
1:java代码注册:
IntentFilter filter = new IntentFilter("android.broadcastreceiver.mreceiver");
mBroadcastReceiver receiver = new mBroadcastReceiver();
registerReceiver(receiver, filter);
2:AndroidManifest.xml文件配置:
<receiver android:name=".mBroadcastReceiver" >
<intent-filter>
<action android:name="android.broadcastreceiver.mreceiver" />
</intent-filter>
</receiver>
注:如果BroadcastReceiver中的onReceiver()方法不能在10秒内执行完成,Android会认为该程序无响应,所以不要再BroadcastReceiver中写一些耗时操作否则ANR。
例子:
客户端:
public classMainActivity extends Activity {
private Button button;
@Override
protected void onCreate(BundlesavedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
button = (Button)findViewById(R.id.button1);
button.setOnClickListener(newOnClickListener() {
@Override
public void onClick(Viewv) {
Intent intent = new Intent();
intent.setAction("android.broadcastreceiver.mreceiver");
Bundle bundle = new Bundle();
bundle.putString("msg", "阿萨德理发卡坚实的");
intent.putExtras(bundle);
sendBroadcast(intent);
}
});
}
}
BroadcastReceiver:
public classmBroadcastReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context,Intent intent) {
Bundle bundle =intent.getExtras();
String string =bundle.getString("msg");
System.out.println(string);
}
}
AndroidManifest.xml:
<receiver android:name=".mBroadcastReceiver" >
<intent-filter>
<actionandroid:name="android.broadcastreceiver.mreceiver" />
</intent-filter>
</receiver>
经过上面这个例子我们基本了解了Android中BroadcastReceiver的使用下面我们来更加完整的学习BroadcastReceiver。
Broadcast分类:
1:Normal Broadcast(普通广播):Normal Broadcast是完全异步的,可以在同一时刻(逻辑上)被所有的接收者接收到,消息传递的效率比较高。但缺点是接收者不能将处理结果传递给下一个接收者,并且无法终止Broadcast Intent的传播。
2:Ordered Broadcas(有序广播):Ordered Broadcast的接收者将按照预先声明的优先级接收Broadcast。eg:A的优先级高于B,B高于C,那么广播接收的顺序就是A->B->C。并且A或B或C都有权终止广播的Broadcas Intent的传递。一旦终止后面的Broadcast接收者都不能接收到Broadcast。另Ordered Broadcast的接收者可以将数据传递给下一个数据的接收者,eg:A得到Broadcast后调用setResultExtras(Bundle)往他的结果对象中传入数据,当Broadcast传给B,B可以通过Bundle b = getResultExtras(true),从A的结果对象中得到A存入的数据。
例子:
Activity:
public class MainActivity extends AppCompatActivity {
private Button button;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
button = (Button)findViewById(R.id.button);
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent();
intent.setAction("android.receiver.myreceiver");
intent.putExtra("msg","消息来自Activity");
//发送有序广播
sendOrderedBroadcast(intent,null);
}
});
}
}
MyReceiver:
public class MyReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
System.out.println("消息:"+intent.getStringExtra("msg"));
Bundle bundle = new Bundle();
bundle.putString("first","消息来自MyReceiver");
//将bundle放入结果
setResultExtras(bundle);
//取消Broadcast的传播
// abortBroadcast();
}
}
MyReceiver2:
public class MyReceiver2 extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
Bundle bundle = getResultExtras(true);
//解析前一个BroadcastReceiver所存入的key为first的消息
String firstString = bundle.getString("first");
System.out.println("消息:"+firstString);
}
}
AndroidManifest.xml:
<receiver android:name=".MyReceiver">
<intent-filter android:priority="20">
<action android:name="android.receiver.myreceiver"></action>
</intent-filter>
</receiver>
<receiver android:name=".MyReceiver2">
<intent-filter android:priority="0">
<action android:name="android.receiver.myreceiver"></action>
</intent-filter>
</receiver>
从上面的例子中我们可以看出,一个程序中包含两个BroadcastReceiver 但是两个BroadcastReceiver 优先级不同,则按优先级顺序先后传递,并且优先级高的BroadcastReceiver 可以给优先级低的BroadcastReceiver 传递数据,而且优先级高的BroadcastReceiver 可以取消Broadcast的传递如代码中注释掉的语句。