美文网首页
Android BroadcastReceiver的创建方式有几

Android BroadcastReceiver的创建方式有几

作者: keepWriteCode | 来源:发表于2019-06-04 20:56 被阅读0次
    1.BroadcastReceiver是什么?

    BroadcastReceiver是Android的四大组件之一,Android系统发送的广播,在BroadcastReceiver中接收,因此BroadcastReceiver即广播接收者。广播是一种跨进程通信的方式,我们在应用程序中发出的广播,不仅在自己的应用程序中能收到,而且其他的应用程序也可以收到。广播是系统全局的,夸进程的,因此可进行组件通信,多线程通信,跨进程通讯,跨应用通信等。例如,当手机电量不足时,系统会发送一个电量不足的广播,此时,系统内的所有的应用都能接收到这个广播。当然,除了系统广播以外,我们在实际开发中也能发送自定义广播。
    1.发送自定义广播

     // 发送一个ACTION为MY_CUSTOM_BROADCAST的自定义广播
            Intent broadcastInt = new Intent();
            broadcastInt.setAction("MY_CUSTOM_BROADCAST");
            sendBroadcast(broadcastInt);
    

    在AndroidManifest.xml文件里注册广播接收者,设置ACTION为MY_CUSTOM_BROADCAST

    <receiver android:name=".com.text.broadcast.MyBroadcastReceiver">
                <intent-filter>
                    <action android:name="MY_CUSTOM_BROADCAST"/>
                </intent-filter>
            </receiver>
    

    然后实现自定义广播接收者
    必须继承BroadcastReceiver并实现抽象方法onReceive
    由于广播接收者默认在主线程运行,因此在onReceive中不能做耗时操作,否则会导致ANR
    在onReceive既可以接收系统广播,也可以接收自定义广播。

    public class MyBroadcastReceiver extends BroadcastReceiver {
        @Override
        public void onReceive(Context context, Intent intent) {
            Log.i("MyBroadcastReceiver","接收到静态注册的广播了");
        }
    }
    

    最后当点击Activity的按钮发送自定义广播的时候Log打印如下

    06-04 03:59:12.926 3685-3685/com.text.demo I/MyBroadcastReceiver: 接收到静态注册的广播了
    
    2.BroadcastReceiver有几种创建方式?

    BroadcastReceiver有2种注册方式
    1.静态注册即在AndroidManifest.xml注册广播接收者,静态广播是通过PackageManagerService在app初始化的时候由系统注册的。
    如上文提到的自定义广播,这个广播只有一个ACTION,而想实际开发中我们可以给广播接收者设置多个ACTION,并且可以在接收者的onReceive中判断ACTION。

    <receiver android:name=".com.text.broadcast.MyBroadcastReceiver">
                <intent-filter>
                    <action android:name="MY_CUSTOM_BROADCAST"/>
                    <action android:name="MY_CUSTOM_BROADCAST1"/>
                </intent-filter>
            </receiver>
    

    发送自定义广播

    // 发送名为MY_CUSTOM_BROADCAST的自定义广播
            if(v.getId() == bt.getId()){
                Intent broadcastInt = new Intent();
                broadcastInt.setAction("MY_CUSTOM_BROADCAST");
                sendBroadcast(broadcastInt);
            }else if(v.getId() == sendBt.getId()){
                Intent broadcastInt = new Intent();
                broadcastInt.setAction("MY_CUSTOM_BROADCAST1");
                sendBroadcast(broadcastInt);
            }
    

    接收广播

    public class MyBroadcastReceiver extends BroadcastReceiver {
        @Override
        public void onReceive(Context context, Intent intent) {
            if(intent.getAction() == "MY_CUSTOM_BROADCAST"){
                Log.i("MyBroadcastReceiver","接收到静态注册的广播了-MY_CUSTOM_BROADCAST");
            }else if(intent.getAction() == "MY_CUSTOM_BROADCAST1"){
                Log.i("MyBroadcastReceiver","接收到静态注册的广播了-MY_CUSTOM_BROADCAST1");
            }
        }
    }
    

    最后的输出结果

    06-04 04:13:35.472 3959-3959/com.text.demo I/MyBroadcastReceiver: 接收到静态注册的广播了-MY_CUSTOM_BROADCAST
    06-04 04:13:38.884 3959-3959/com.text.demo I/MyBroadcastReceiver: 接收到静态注册的广播了-MY_CUSTOM_BROADCAST1
    

    2.动态注册即调用registerReceiver方法注册。注:在Activity中最好是在onResume方法中调用registerReceiver注册,在onDestroy方法中调用unregisterReceiver注销广播,否则会造成内存泄露。
    注册,设置IntentFilter的ACTION为REGISTER_BROADCAST

    @Override
        protected void onResume() {
            super.onResume();
            // 动态注册广播
            receiver = new MyBroadcastReceiver();
            IntentFilter filter = new IntentFilter("REGISTER_BROADCAST");
            registerReceiver(receiver,filter);
        }
    

    销毁,Activity销毁时注销广播接收者

    @Override
        protected void onDestroy() {
            super.onDestroy();
            // 销毁广播
            unregisterReceiver(receiver);
        }
    

    接收广播则和静态注册一样。

    3.BroadcastReceiver2种创建方式的异同?

    动态注册的优点和缺点(确认下8.0是否不允许静态注册)
    动态注册广播接收者相对静态注册来说要更灵活,用的时候随时注册,但需要及时销毁,否则容易造成内存泄露。
    静态注册的优点和缺点
    静态注册则是在APP初始化的时候就注册了,不需要注册和销毁动作,也就不存在不销毁就内存泄露的风险。

    4.如何给BroadcastReceiver设置优先级?

    广播分为普通广播和有序广播。普通广播为完全异步的,是可以同时被所有的广播接收者接收到,并且广播接收者收到广播后无法终止广播。而有序广播则有先后之分,且广播可以被广播接收者拦截和终止,调用abortBroadcast()方法即可终止。给有序广播设置priority属性,priority的取值范围是-1000~10000,值越大广播的优先级越高。广播接收者处理了有序广播后还可以将处理结果存入数据(可通过setResultExtras(Bundle)方法将数据存入Broadcast),当做Broadcast再传递给下一级接收者(可通过代码Bundle bundle = getResultExtras(true)获取上一级传递过来的数据)
    日志结果MY_CUSTOM_BROADCAST优先级大于MY_CUSTOM_BROADCAST1,当接收到MY_CUSTOM_BROADCAST时终止广播,因此MyReceive里面就接收不到了。
    代码示例

    <receiver
                android:name=".com.text.broadcast.MyBroadcastReceiver">
                <intent-filter android:priority="13">
                    <action android:name="MY_CUSTOM_BROADCAST"/>
                </intent-filter>
    
                <intent-filter android:priority="10">
                    <action android:name="MY_CUSTOM_BROADCAST1"/>
                </intent-filter>
            </receiver>
            <receiver android:name=".com.text.broadcast.MyReceive">
                <intent-filter android:priority="13">
                    <action android:name="MY_CUSTOM_BROADCAST"/>
                </intent-filter>
    
                <intent-filter android:priority="10">
                    <action android:name="MY_CUSTOM_BROADCAST1"/>
                </intent-filter>
            </receiver>
    
    // 发送有序广播
            if(v.getId() == bt.getId()){
                Intent broadcastInt = new Intent();
                broadcastInt.setAction("MY_CUSTOM_BROADCAST");
                sendOrderedBroadcast(broadcastInt,null);
            }else if(v.getId() == sendBt.getId()){
                Intent broadcastInt = new Intent();
                broadcastInt.setAction("MY_CUSTOM_BROADCAST1");
                sendOrderedBroadcast(broadcastInt,null);
            }
    
    public class MyBroadcastReceiver extends BroadcastReceiver {
        @Override
        public void onReceive(Context context, Intent intent) {
            if(intent.getAction() == "MY_CUSTOM_BROADCAST"){
                Log.i("MyBroadcastReceiver","接收到静态注册的广播了-MY_CUSTOM_BROADCAST");
                abortBroadcast();
            }else if(intent.getAction() == "MY_CUSTOM_BROADCAST1"){
                Log.i("MyBroadcastReceiver","接收到静态注册的广播了-MY_CUSTOM_BROADCAST1");
            }
        }
    }
    
    public class MyReceive extends BroadcastReceiver {
        @Override
        public void onReceive(Context context, Intent intent) {
            if(intent.getAction() == "MY_CUSTOM_BROADCAST"){
                Log.i("MyReceive","接收到静态注册的广播了-MY_CUSTOM_BROADCAST");
                abortBroadcast();
            }else if(intent.getAction() == "MY_CUSTOM_BROADCAST1"){
                Log.i("MyReceive","接收到静态注册的广播了-MY_CUSTOM_BROADCAST1");
            }
        }
    }
    

    这是输出结果

    06-04 05:16:29.570 5388-5388/com.text.demo I/MyBroadcastReceiver: 接收到静态注册的广播了-MY_CUSTOM_BROADCAST
    06-04 05:16:34.379 5388-5388/com.text.demo I/MyBroadcastReceiver: 接收到静态注册的广播了-MY_CUSTOM_BROADCAST1
    06-04 05:16:34.382 5388-5388/com.text.demo I/MyReceive: 接收到静态注册的广播了-MY_CUSTOM_BROADCAST1
    
    5.有哪些常用的系统广播?

    Intent.ACTION_BATTERY_LOW
    //低电量广播
    Intent.ACTION_BATTERY_OKAY
    //充电完成广播
    Intent.ACTION_BOOT_COMPLETED
    //系统启动完成广播
    Intent.ACTION_CAMERA_BUTTON
    //拍照按钮广播
    Intent.ACTION_DATE_CHANGED
    //系统生日改变广播
    Intent.ACTION_DEVICE_STORAGE_LOW
    //系统内存不足广播
    另附开发文档链接:https://developer.android.google.cn/guide/components/broadcast-exceptions

    5.广播的通讯原理是什么?

    1..广播的发送和接收模式,实际上是消息的发布和订阅模式,属于广义的观察者模式。
    2.广播的发送为完全异步,只管发送而不管是否有接收,什么时候被接收,接收后也不需要callback。
    3.广播发送者通过Binder机制发送广播到消息队列,广播接收者通过Binder机制在ActivityManagerService进行注册,当消息循环机制找到符合条件(IntentFilter/Action/Permission)的广播接收者时调用对应的广播接收者的onReceive().

    相关文章

      网友评论

          本文标题:Android BroadcastReceiver的创建方式有几

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