美文网首页
BroadcastRecevicer

BroadcastRecevicer

作者: Drew_MyINTYRE | 来源:发表于2021-07-03 11:21 被阅读0次

    动态广播最好在 Activity 的 onResume()注册、onPause()注销。

    广播的两种注册方式的区别?

    广播的分类和使用场景?

    1,系统广播

    Android中内置了多个系统广播:只要涉及到手机的基本操作(如开机、网络状态变化、拍照等等),都会发出相应的广播。
    例如:重启设备 ->Intent.ACTION_REBOOT

    每个广播都有特定的Intent - Filter(包括具体的action),当使用系统广播时,只需要在注册广播接收者时定义相关的 action 即可,并不需要手动发送广播,当系统有相关操作时会自动进行系统广播。

    2,本地广播(本地广播和全局广播的区别?)

    广播的发送者和接收者都同属于一个 App。相比于全局广播,它的优势体现在:安全性高 & 效率高。

    如何将全局广播设置成本地广播?

    • 注册广播时将 exported 属性设置为 false,使得非本 App 内部发出的此广播不被接收;

    • 在广播发送和接收时,增设相应 permission,用于权限验证;

    • 发送广播时指定广播接收器所在的包名,此广播将只会发送到与之相匹配的且包名有效的广播接收器中。(通过 intent.setPackage(packageName) 指定包名)

    最简单的办法就是直接使用LocalBroadcastManager,怎么使用它呢?

    使用方式上与自定义广播几乎相同,对于 LocalBroadcastManager 方式发送的应用内广播,只能通过 LocalBroadcastManager 动态注册,不能静态注册。

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        instance = LocalBroadcastManager.getInstance(this);
        IntentFilter intentFilter = new IntentFilter();
        intentFilter.addAction("android.net.conn.CONNECTIVITY_CHANGE");
        myLocalBroadcast = new MyLocalBroadcast();
        instance.registerReceiver(myLocalBroadcast, intentFilter);
    }
    
    class MyLocalBroadcast extends BroadcastReceiver{
    
        @Override
        public void onReceive(Context context, Intent intent) {
            Toast.makeText(context , "本地广播" , Toast.LENGTH_SHORT).show();
        }
    }
    
    @Override
    protected void onDestroy() {
        super.onDestroy();
        instance.unregisterReceiver(myLocalBroadcast);
    }
    

    对于不同的注册方式,广播接收器回调 OnReceive(Context context,Intent intent)中的 context 值是不一样的:

    • 对于静态注册,回调 onReceive(context, intent) 中的 context 是:ReceiverRestrictedContext

    • 对于全局广播动态注册,回调 onReceive(context, intent) 中的 context 是:Activity

    • 对于本地广播动态注册(LocalBroadcastManager 方式),回调onReceive(context, intent) 中的 context 是:Application

    广播发送和接收的原理

    • 接收者 通过 Binder 机制在 AMS 注册

    • 发送者 通过 Binder 机制向 AMS 发送广播

    • AMS 根据发送者的 IntentFilter / Permission ,在已注册的列表中,寻找合适的接收者。

    • 如果找到了接收者,AMS 将广播发送到目标接收者的消息循环的队列中

    • 接收者通过消息循环拿到该广播,并回调 onReceive (...)

    特别注意:广播发送者和广播接收者的执行是异步的,发的人不关心你有没有收到,也不会关心你何时收到。

    思考题:

    • LocalBroadcastReceiver为何比 BroadCastReceiver 速度快?

    LocalBroadcastReceiver 是本地广播,只能在应用内使用和接收。BroadcastReceiver 是针对应用间、应用与系统间、应用内部进行通信的一种方式,利用 Binder 机制实现,支持动态和静态两种方式注册方式。LocalBroadcastReceiver 是应用内广播,利用 Handler 实现,利用了 IntentFiltermatch 功能,提供消息的发布与接收功能,实现应用内通信,效率和安全性比较高,仅支持动态注册。

    普通广播是什么?

    调用 sendBroadcast() 发送

    有序广播是什么?

    调用 sendOrderedBroadcast() 发送,广播接收者会按照 priority 优先级从大到小进行排序,优先级相同的广播,动态注册的广播优先处理,广播接收者还能对广播进行截断和修改。

    本地广播的优点?

    效率更高。发送的广播不会离开我们的应用,不会泄露关键数据。其他程序无法将广播发送到我们程序内部,不会有安全漏洞。

    现在 BroadcastReceiver 也不推荐使用静态注册了,8.0 之后限制了绝大部分广播只能使用动态注册。

    相关文章

      网友评论

          本文标题:BroadcastRecevicer

          本文链接:https://www.haomeiwen.com/subject/plyuultx.html