Android四大组件--BroadcastReceiver

2019-04-09  本文已影响0人  zerohdq

简介

在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 应用很少或者说只做很少的交互的话,使用广播真的就是一种浪费!!!

上一篇下一篇

猜你喜欢

热点阅读