广播机制介绍
Android中广播分为标准广播和有序广播,标准广播是一种完全异步执行的广播,广播发出后,所有广播接收器机会会在同一时刻接收到广播,但同时意味着它也是无法被截断的。有序广播是一种同步执行的广播,同一时刻只有一个广播接收器能收到这条消息,当这个广播接收器的逻辑执行完毕之后才会继续传递,优先级高的广播接收器可以先收到广播,并且还可以阶段正在传递的广播,这样后面的广播接收器就收不到这条广播消息。
动态注册和静态注册广播
动态注册一般在Activity的onCreate方法中写上类似于:
1 | IntentFilter filter = new IntentFilter(); |
并且在onDestroy方法中注销广播:
1 | > unregisterReceiver(receiver); |
然后,完善一般是内部类的MyReceiver:
1 | class MyReceiver extends BroadcastReceiver{ |
最后得在适当的时候发送广播:
1 | Intent intent = new Intent("com.example.MyReceiver"); |
当然,如果你是用广播在APP中实现强制退出登录(如QQ账号在另一台设备上登录了),那你只需要在当前Activity上弹一个窗提示已经被强制下线即可,因此有必要将广播在BaseActivity中注册,并且在BaseActivity的onPause方法(注意不是onDestroy方法了,因为我们只需要栈顶的Activity能够响应就行)中注销广播即可。如果是接收系统级广播,可能还得在AndroidManife.xml中声明相关权限。APP中实现强制退出登录时的广播接收器可以这样写:
1 | class ForceOfflineReceiver extends BroadcastReceiver{ |
静态注册广播是在AndroidManife.xml中做如下的声明,其中MyReceiver类一般不是内部类,因为即使app未启动也能接收广播:
1 | <application |
如果要发送有序广播,只需要将以上发送广播的代码sendBroadcast(intent)替换成sendOrderedBroadcast(intent,null);即可。设置广播的优先级只需要设置intentFilter的priority属性即可(AndroidManifest文件中是intent-filter属性)。
使用本地广播
前面发送的广播属于系统全局广播,发出的广播可以被任何应用接收到,并且我们也可以接受来自其它任何应用发出的广播,这容易引起安全性问题,比如关键数据广播被其他应用截获,或者其他应用发送各种垃圾广播。本地广播的发送有些不同:
1 | LocalBroadcastManager manager = LocalBroadcastManager.getInstance(this); |
注册:
1 | IntentFilter filter = new IntentFilter(); |
同样注销广播:
1 | manager.unregisterReceiver(localReceiver); |
本地广播的几点优势:
- 可以明确地知道正在发送的广播不会离开我们的程序,因此不必担心机密数据泄露。
- 其他的程序无法将广播发送到我们程序内部,因此不用担心会有安全漏洞隐患。
- 发送本地广播比发送系统全局广播更加高效。
另有一点需要说明:本地广播是无法通过静态注册方式来接收的,其实这也完全可以理解,因为静态注册主要就是为了让程序在未启动的情况下也能接收广播,而发送本地广播时,我们的程序肯定是已经启动了;此外,不要再onReceive方法中添加过多的逻辑或者进行任何耗时的操作,因为广播接收器中是不允许开启线程的,当onReceive方法运行了较长时间而没有结束时,程序就会报错。因此它更多的只是扮演一种打开程序其他组件的角色,如弹一条通知,或者启动一个服务等。