Broadcast广播机制
Broadcast广播机制
1、注册方式
1.1 静态注册
使用清单文件进行注册
在AndroidManifest.xml清单文件里直接声明的方式叫做静态注册。
<receiver
//此广播接收者类是mXRReceiver
android:name=".mXRReceiver" >
//用于系统启动完成时,接收系统发送的广播
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
<receiver
android:enabled=["true" | "false"]
//此broadcastReceiver能否接收其他App的发出的广播
//默认值是由receiver中有无intent-filter决定的:如果有intent-filter,默认值为true,否则为false
android:exported=["true" | "false"]
android:icon="drawable resource"
android:label="string resource"
//继承BroadcastReceiver子类的类名
android:name=".mXRReceiver"
//具有相应权限的广播发送者发送的广播才能被此BroadcastReceiver所接收;
android:permission="string"
//BroadcastReceiver运行所处的进程
//默认为app的进程,可以指定独立的进程
//注:Android四大基本组件都可以通过此属性指定自己的独立进程
android:process="string" >
//用于指定此广播接收器将接收的广播类型
//本示例中给出的是用于系统启动完成时,接收系统发送的广播
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
1.2 动态注册
在代码中进行注册
private void initBroadcastReceiver() {
if (mXRBroadcastReceiver == null) {
mXRBroadcastReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
...
}
};
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction(Intent.BOOT_COMPLETE);
registerReceiver(mXRBroadcastReceiver, intentFilter);
}
}
注意:动态广播最好在Activity的onResume()注册、onPause()注销。一旦忘记注销,那么就会造成内存泄露哦。
2 Broadcast的分类
1、普通广播
2、系统广播
3、有序广播
4、粘性广播
5、本地广播
2.1 普通广播
也就是标准广播,是一种完全异步执行的广播,和学校大喇叭完全一样,发出广播后,所有广播接收者都能收到广播,且没有优先之分,上面程序都是普通广播。
2.2 系统广播
监听网络变化 | android.net.conn.CONNECTIVITY_CHANGE |
---|---|
关闭或打开飞行模式 | Intent.ACTION_AIRPLANE_MODE_CHANGED |
充电时或电量发生变化 | Intent.ACTION_BATTERY_CHANGED |
电池电量低 | Intent.ACTION_BATTERY_LOW |
电池电量充足(即从电量低变化到饱满时会发出广播 | Intent.ACTION_BATTERY_OKAY |
系统启动完成后(仅广播一次) | Intent.ACTION_BOOT_COMPLETED |
按下照相时的拍照按键(硬件按键)时 | Intent.ACTION_CAMERA_BUTTON |
屏幕锁屏 | Intent.ACTION_CLOSE_SYSTEM_DIALOGS |
设备当前设置被改变时(界面语言、设备方向等) | Intent.ACTION_CONFIGURATION_CHANGED |
插入耳机时 | Intent.ACTION_HEADSET_PLUG |
未正确移除SD卡但已取出来时(正确移除方法: | |
设置–SD卡和设备内存–卸载SD卡) | Intent.ACTION_MEDIA_BAD_REMOVAL |
插入外部储存装置(如SD卡) | Intent.ACTION_MEDIA_CHECKING |
成功安装APK | Intent.ACTION_PACKAGE_ADDED |
成功删除APK | Intent.ACTION_PACKAGE_REMOVED |
重启设备 | Intent.ACTION_REBOOT |
屏幕被关闭 | Intent.ACTION_SCREEN_OFF |
屏幕被打开 | Intent.ACTION_SCREEN_ON |
关闭系统时 | Intent.ACTION_SHUTDOWN |
重启设备 | Intent.ACTION_REBOOT |
2.3 有序广播
有序广播是一种同步执行的广播,按广播接收者的优先级由高到低排序,轮流接收到广播,且前面的广播接收者可以拦截该广播,这样后面的广播接收者就无法接收到该广播了。同时,前面的广播接受者也可以修改该广播并不做拦截,这样下一个接收到的广播就是被修改过的。 设置广播接收者的优先级可以用priority属性,数字越高代表优先级越高,最高是1000.
<receiver
//此广播接收者类是mXRReceiver
android:name=".mXRReceiver" >
//用于系统启动完成时,接收系统发送的广播
<intent-filter android:priority="1000">
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
2.4 本地广播
BroadcastReceiver可用于不同应用之间传递消息,但难免会出现这两种情况:
- 我们的App注册了广播接收者A,同时其他App可能要完成某个操作,碰巧发送了符合接收者A过滤条件的广播,导致我们的App就一直错误的接收到了这个广播;
- 我们的App注册了广播接收者A,同时其他App也碰巧注册了和我们同样过滤条件的广播接收者,这样就导致本来是我们App接收的广播,其他App也接收到了;
基于这两大问题,LocalBroadcastManager就可以很好的解决该问题。LocalBroadcastManager用于应用内部传递消息,比broadcastReceiver更加高效和安全。
2.4.1 为何更加安全
BroadcastReceiver是以 Binder 通讯方式为底层实现的机制不同,众所周知Binder是跨进程的。而LocalBroadcastManager 是利用应用内部的Handler来实现,只是利用到了 IntentFilter 的 match 功能,因为是 Handler 实现的应用内的通信,自然安全性更好,效率更高。
2.4.2 如何实现本地广播
方法一:把全局广播改为本地广播
- 注册广播时将exported属性设置为false,表示该广播接收者不对外;
- 在广播发送和接收时,增设相应权限permission,用于权限验证;
- 发送广播时通过intent.setPackage(packageName)指定该广播接收器所在的包名,因此保证该发送出去的广播只会发送到指定包名的App内的广播接收者。
3、APP1 能否接收到APP2 的广播
当然能,只要使用全局的BroadCastRecevier能进行跨进程通信,不过只能被动接收广播。
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 胡萝卜!