简介
在Android中,Broadcast是一种广泛运用的在应用程序之间传输信息的机制。而BroadcastReceiver是对发送出来的 Broadcast进行过滤接受并响应的一类组件。
内部基本原理
Android 的广播 BroadcastReceiver 是一个全局的监听器,主要用于监听 / 接收应用发出的广播消息,并作出响应。其采用了设计模式中的 观察者模式 ,可将广播基于 消息订阅者 、消息发布者、消息中心(AMS:即 Activity Manager Service)解耦,通过 Binder 机制形成订阅关系。
发送广播
Intent intent = new Intent("com.study.hq.compontentdemo.General");
Bundle bundle=new Bundle();
bundle.putString("key","这时一个普通的广播!");
intent.putExtras(bundle);
//发送广播
sendBroadcast(intent);
新建广播接收者
public class MyBroadcastReceiver extends BroadcastReceiver{
@Override
public void onReceive(Context context, Intent intent) {
Bundle bundle = intent.getExtras();
String value = bundle.getString("key");
Log.e(TAG,value);
}
}
注册广播
静态注册
<receiver android:name=".MainActivity$MyBroadcastReceiver">
<intent-filter>
<action android:name="com.study.hq.compontentdemo.General"/>
</intent-filter>
</receiver>
动态注册
IntentFilter filter = new IntentFilter();
filter.addAction("com.study.hq.compontentdemo.General");
MyBroadcastReceiver receiver = new MyBroadcastReceiver();
registerReceiver(receiver, filter);
/**
* 取消注册
*/
@Override
protected void onDestroy() {
super.onDestroy();
unregisterReceiver(receiver);
}
注册的广播接收者接收到广播
com.study.hdq.componentdemo E/MainActivity: 这时一个普通的广播!
两种注册方式的区别
image广播类型
无序广播
无序广播是完全异步的,通过 Context.sendBroadcast() 方法来发送,从效率上来看,还算是比较高的。正如它的名称一样,无序广播对所有的广播接收者而言,是无序的。也就是说,所有接收者无法确定接收时序的顺序,这样也导致了,无序广播无法被停止。当它被发送出去之后,它将通知所有这条广播的接收者,直到没有与之匹配的广播接收者为止。
有序广播
有序广播通过 Context.sendOrderedBroadcast() 方法来发送。有序广播和无序广播最大的不同,就是它可以允许接收者设定优先级,它会按照接收者设定的优先级依次传播。而高优先级的接收者,可以对广播的数据进行处理或者停止掉此条广播的继续传播。广播会先发送给优先级高 (android:priority) 的 Receiver,而且这个 Receiver 有权决定是继续发送到下一个 Receiver 或者是直接终止广播。
发送有序广播
Intent intent = new Intent("com.study.hq.compontentdemo.General");
Bundle bundle=new Bundle();
bundle.putString("key","这时一个有序的广播!");
intent.putExtras(bundle);
//发送广播
sendOrderedBroadcast(intent,null);
结束有序广播
abortBroadcast();
如果在广播接收器中调用 abortBroadcast( ) 方法,则之后的接收器无法收到该广播。Priority 数值越大,优先级越高,越先收到广播。
本地广播
本地广播机制,使用这个机制发出的广播只能够在应用程序的内部进行传递,并且广播接收器也只能接收本应用程序发出的广播。
LocalBroadcastManager localBroadcastManager=LocalBroadcastManager.getInstance(this);
Intent intent2 = new Intent("com.study.hq.compontentdemo.General");
Bundle bundle2=new Bundle();
bundle2.putString("key","这时一个本地的广播!");
intent2.putExtras(bundle2);
//通过 LocalBroadcastManager 进行广播发送
localBroadcastManager.sendBroadcast(intent2);
粘性广播
Sticky 广播和它的名字很像,它是一个具有粘性的广播。它被发出去之后,会一直滞留在系统中,直到有与之匹配的接收者,才会将其发出去。它采用 Context.sendStickyBroadcast() 方法进行发送广播。
从官方文档上可以看到,如果想要发送一个 Sticky 广播,需要具有 BROADCAST_STICKY 权限,这个可以在 AndroidManifest.xml 中进行注册,而如果没有此权限,则会抛出 SecurityException 异常。
对于系统而言,只会保留最后一条 Sticky 广播,并且会一直保留下去,也就是说,如果我们发送的 Sticky 广播不被取消,当有一个接收者的时候就会收到它,再来一个还是能收到。所有我们需要在合适的实际,调用 removeStickyBoradcast() 方法,将其取消掉。
使用场景
众所周知,广播是 Android 的四大组件之一。系统级的事件都是通过广播来通知的,比如说网络的变化、电量的变化、短信接收和发送状态等。所以,如果是和 Android 系统相关的通知,我们还得选择本地广播。
但是!!!广播相对于其他实现方式,是很重量级的,它消耗的资源较多。它的优势体现在和 SDK 的紧密联系,onReceive() 方法自带了 Context 和 Intent 参数,所以在一定意义上实现了便捷性,但如果对 Context 和 Intent 应用很少或者说只做很少的交互的话,使用广播真的就是一种浪费!!!
网友评论