一、前言
今天来看一下Android中的广播机制,我们知道广播Broadcast是Android中的四大组件之一,可见他的重要性了,当然它的用途也很大的,比如一些系统的广播:电量低、开机、锁屏等一些操作都会发送一个广播。
二、广播机制
广播被分为两种不同的类型:“普通广播(Normal broadcasts)”和“有序广播(Ordered broadcasts)”。
普通广播(Normal broadcasts):
普通广播是完全异步的,可以在同一时刻(逻辑上)被所有广播接收者接收到,消息传递的效率比较高,但缺点是:接收者不能将处理结果传递给下一个接收者,并且无法终止广播Intent的传播;
有序广播(Ordered broadcasts):
有序广播是按照接收者声明的优先级别(声明在intent-filter元素的android:priority属性中,数越大优先级别越高,取值范围:-1000到1000。也可以调用IntentFilter对象的setPriority()进行设置),被接收者依次接收广播。如:A的级别高于B,B的级别高于C,那么,广播先传给A,再传给B,最后传给C。A得到广播后,可以往广播里存入数据,当广播传给B时,B可以从广播中得到A存入的数据。
Context.sendBroadcast()
发送的是普通广播,所有订阅者都有机会获得并进行处理。
Context.sendOrderedBroadcast()
发送的是有序广播,系统会根据接收者声明的优先级别按顺序逐个执行接收者,前面的接收者有权终止广播(BroadcastReceiver.abortBroadcast()),如果广播被前面的接收者终止,后面的接收者就再也无法获取到广播。对于有序广播,前面的接收者可以将处理结果存放进广播Intent,然后传给下一个接收者。
广播接收:
广播接收者(BroadcastReceiver)用于接收广播Intent,广播Intent的发送是通过调用Context.sendBroadcast()、Context.sendOrderedBroadcast()来实现的。通常一个广播Intent可以被订阅了此Intent的多个广播接收者所接收,这个特性跟JMS中的Topic消息接收者类似。要实现一个广播接收者方法如下:
第一步:定义广播接收者,继承BroadcastReceiver,并重写onReceive()方法。
public class BroadCast extends BroadcastReceiver {
@Override public void onReceive(Contextcontext, Intentintent) {
}
}
第二步: 注册广播Intent,方法有两种:
第一种:使用代码进行订阅(动态注册)
IntentFilter filter = new IntentFilter("com.llay.admin.mydemo.sendMessage");
BroadCast receiver = new BroadCast ();
registerReceiver(receiver, filter);
第二种:在AndroidManifest.xml文件中的节点里进行订阅(静态注册)
<receiver android:name=".BroadCast">
<intent-filter>
<action android:name="com.llay.admin.mydemo.sendMessage"/>
</intent-filter>
</receiver>
注意:
静态订阅广播又叫:常驻型广播,当你的应用程序关闭了,如果有广播信息来,你写的广播接收器同样的能接受到,他的注册方式就是在你的应用程序中的AndroidManifast.xml进行订阅的。
动态订阅广播又叫:非常驻型广播,当应用程序结束了,广播自然就没有了,比如你在activity中的onCreate或者onResume中订阅广播,同时你必须在onDestory或者onPause中取消广播订阅。不然会报异常,这样你的广播接收器就一个非常驻型的了。
三、代码的实现(使用Intent启动广播,可以显示启动,也可以隐示启动,这里显示启动忽略)
3、1 普通广播(Normal broadcasts)
(静态注册)
1、布局界面:
2、广播代码
NormalBroadCast.java文件,用来接收activity中发送的数据
public class NormalBroadCast extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
String s = intent.getStringExtra("xiaomi");
Log.e("NormalBroadCast", s);
}
}
3、activity中的代码
String s = editNormal.getText().toString();
//Intent intent = new Intent(BroadcastReceiverActivity.this, NormalBroadCast.class);//显示启用广播
Intent intent1 = new Intent("com.llay.admin.mydemo.sendMessage");
intent1.putExtra("xiaomi", s);
sendBroadcast(intent1);
break;
4、AndroidManifests.xml文件中静态注册该广播
<receiver android:name="com.llay.admin.broadcast.NormalBroadCast">
<intent-filter>
<action android:name="com.llay.admin.mydemo.sendMessage" />
</intent-filter>
</receiver>
结果:运行结果图:
输入文字,点击发送广播按钮:
(动态注册注册)
1、布局界面同上
2、广播代码同上
3、Actvity中代码
public class BroadcastReceiverActivity extends AppCompatActivity implements View.OnClickListener {
private EditText editNormal;
private Button buttonNormal, buttonOrdered;
NormalBroadCast normalBroadCast;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_broadcast_receiver);
init();
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction("com.llay.admin.mydemo.sendMessage");
normalBroadCast = new NormalBroadCast();
registerReceiver(normalBroadCast, intentFilter);
Log.e("xiaomi", "注册广播");
}
private void init() {
editNormal = (EditText) findViewById(R.id.normal_edit);
buttonNormal = (Button) findViewById(R.id.normal_button);
buttonOrdered = (Button) findViewById(R.id.ordered_button);
buttonNormal.setOnClickListener(this);
buttonOrdered.setOnClickListener(this);
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.normal_button:
String s = editNormal.getText().toString();
//Intent intent = new Intent(BroadcastReceiverActivity.this, NormalBroadCast.class);//显示启动广播
Intent intent1 = new Intent("com.llay.admin.mydemo.sendMessage");
intent1.putExtra("xiaomi", s);
sendBroadcast(intent1);
break;
}
}
@Override
protected void onDestroy() {
super.onDestroy();
unregisterReceiver(normalBroadCast);
Log.e("xiaomi", "取消广播");
}
注意:动态注册广播的时候,必须要你在activity中的onCreate或者onResume中订阅广播,同时你必须在onDestory或者onPause中取消广播订阅。
4、AndroidManifest.xml中注册广播
<receiver android:name="com.llay.admin.broadcast.NormalBroadCast">
</receiver>
结果:运行结果图:
输入文字,点击发送广播按钮:
3、2 有序广播(Ordered broadcasts)
注意:这里我就直接用静态注册广播了,这也是推荐使用的。因为动态注册会随应用的关闭而消失。
1、布局文件同上
2、广播代码
A广播:
OrderedBroadCastA.java文件:
public class OrderedBroadCastA extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
String s = intent.getStringExtra("xiaomi");
Log.e("orderedA", s);
//终止Ordered广播传递
// abortBroadcast();
Bundle bundle = new Bundle();
bundle.putString("传递给下一个广播", "ss");
setResultExtras(bundle);
}
注意:其中广播A可以使用abortBroadcast()来使得传递给下一个的广播终止,使用setResultExtras()来将数据从此广播传递给下一个广播。
3、Actvity中代码
String s1 = editNormal.getText().toString();
Intent intent2 = new Intent("com.llay.admin.mydemo.sendMessage");
intent2.putExtra("xiaomi", s1);
sendOrderedBroadcast(intent2, null);
break;
4、AndroidManifest.xml中注册广播
<!--优先级高-->
<receiver android:name="com.llay.admin.broadcast.OrderedBroadCastA">
<intent-filter android:priority="2">
<action android:name="com.llay.admin.mydemo.sendMessage" />
</intent-filter>
</receiver>
<!--优先级低-->
<receiver android:name="com.llay.admin.broadcast.OrderedBroadCastB">
<intent-filter android:priority="1">
<action android:name="com.llay.admin.mydemo.sendMessage" />
</intent-filter>
</receiver>
注意:这里都是采用的是静态的注册广播的方式,android:priority属性是设置优先级,数字越大,优先级越高,越会先执行。
结果:运行结果图:
输入文字,点击发送广播按钮
此处A广播中使用abortBroadcast();方法
此处A广播不使用abortBroadcast();方法