原理
取自https://www.jianshu.com/p/ca3d87a4cdf3- 订阅者在AMS注册
- 发布者发送广播到AMS
- 广播的流转由AMS控制
class MyBroadcastReceiver : BroadcastReceiver() {
override fun onReceive(context: Context?, intent: Intent?) {
Log.i("ljf", "onReceive")
}
}
广播被接收后,回调onReceive
静态注册
在manifest声明receiver
<receiver android:name=".MyBroadcastReceiver"/>
四大组件声明必备,动态注册到此是一致的。
静态注册必须声明intent-filter,用于指明所接收的广播。
<receiver android:name=".MyBroadcastReceiver">
<intent-filter>
<action android:name="ljf" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</receiver>
Category为四大组件分类,多组件同action时可根据intent中的category确定组件
常见:
CATEGORY_DEFAULT:Android系统中默认的执行方式,按照普通Activity的执行方式执行。
CATEGORY_HOME:设置该组件为Home Activity。
CATEGORY_PREFERENCE:设置该组件为Preference。
CATEGORY_LAUNCHER:设置该组件为在当前应用程序启动器中优先级最高的Activity,通常为入口ACTION_MAIN配合使用。
CATEGORY_BROWSABLE:设置该组件可以使用浏览器启动。
CATEGORY_GADGET:设置该组件可以内嵌到另外的Activity中。
通过静态注册的receiver,在首次启动时注册到AMS,并常驻系统中。
由于Android系统的限制,静态注册无法获得系统广播(大大部分),见下系统广播
动态注册
通过代码进行注册、注销操作
val intentFilter=IntentFilter()
intentFilter.addAction("ljf")
intentFilter.addCategory("android.intent.category.DEFAULT")
registerReceiver(receiver, filter)
unregisterReceiver(receiver)
动态注册并不会常驻,而是与绑定者生命周期一致。注册、注销要成对出现,否则当绑定者结束会报异常
普通广播
发布者发送广播,各个接收者接收广播是独自进行的并不会互相影响。
val intent = Intent("ljf")
intent.action="ljf"
intent.addCategory("android.intent.category.DEFAULT")
sendBroadcast(intent)
有序广播
发布者发送广播,广播按接收者的优先级,由高优先级向低优先级传递
<intent-filter android:priority="1000"> //-1000 至 1000
高优先级的接收者向下传递广播也可中止广播的传递,在向低优先级的receiver传递时也可以添加中途处理的数据
abortBroadcast()
setResultExtras(Bundle())
getResultExtras(boolean) //这里的Boolean为null处理
发送有序广播需要指明permission,只有符合的receiver才可接收,permission为null表示不要求receiver
sendOrderedBroadcast(intent, "permission")
接收者需声明自定义permission
<permission android:protectionLevel="normal" //permission等级
android:name="permission" />
并使用此权限
<uses-permission android:name="permission" />
系统广播
由系统发出的广播,但随着Android系统升级Google对权限和性能的管理逐步细化
从Android 3.1开始,系统给Intent定义了两个新的Flag,分别为FLAG_INCLUDE_STOPPED_PACKAGES(表示包含未启动的App)和FLAG_EXCLUDE_STOPPED_PACKAGES(表示不包含未启动的App),用来控制Intent是否要对处于停止状态的APP起作用
系统广播基本都FLAG_EXCLUDE_STOPPED_PACKAGES,所以当APP被stop后,即使静态注册的receiver也不会收到广播
当自己开发多进程间的功能时,如果发广播给另外的APP切记加FLAG_INCLUDE_STOPPED_PACKAGES
接收系统广播时还是用动态注册比较保险,以防Google和国内rom
网友评论