这是我参与「第四届青训营 」笔记创作活动的第13天。
广播(Broadcast)是Android系统中的一种进程间通信的手段。Android应用与Android系统、Android应用之间都可以相互收发广播消息,例如,Android系统会在各种系统事件发生时发送广播,像网络状态发生改变、开始充电等,Android应用也可以自定义广播并发送,从而实现进程间通信。
在Android中,存在两种Broadcast:
- 标准广播(无序广播):这是一种完全异步执行的广播,效率较高,在广播发出后,所有广播接收者都会几乎在同时收到广播信息
- 有序广播:这是一种同步执行的广播,同一时刻只会有一个广播接收者收到广播信息,并会在广播接收者执行完成处理逻辑之后才会传送给下一个广播接收者。有序广播会按照广播接收者的优先级来传送,优先级高的接收者优先接收广播。除此之外,广播接收者可以选择拦截广播,使广播不再继续传播。
基本用法
广播接收者需要注册自己要接收的广播,在广播发出后,Android系统将会自动把广播信息推送给接收者。接收广播需要借助于BroadcastReceiver类来进行,通常做法是定义一个BroadcastReceiver的子类,并在其中写下广播处理逻辑。
接收广播
有两种注册广播接收器的方法,分别是通过AndroidManifest文件进行静态注册和通过Java或Kotlin代码动态注册:
- 静态注册
- 如下所示,其中
<intent-filter>中的内容指定了接收器要接收的广播信息
<receiver android:name=".MyBroadcastReceiver" android:exported="true"> <intent-filter> <action android:name="android.intent.action.BOOT_COMPLETED"/> <action android:name="android.intent.action.INPUT_METHOD_CHANGED" /> </intent-filter> </receiver>- 在AndroidManifest文件中进行定义后,还需要在Kotlin或者Java代码文件中创建对应的BroadcastReceiver子类,例如上面的AndroidManifest文件中的
android:name属性为.MyBroadcastReceiver,就需要创建一个名为MyBroadcastReceiver的BroadcastReceiver子类来接收定义的广播,如下所示
class MyBroadcastReceiver : BroadcastReceiver() { override fun onReceive(context: Context, intent: Intent) { //广播处理逻辑 } } - 如下所示,其中
- 动态注册
- 除了上面的静态注册,还可以直接在Kotlin或Java代码中进行动态注册,而无需在AndroidManifest文件中定义。具体做法是,首先创建一个BroadcastReceiver(或者它的子类)的实例,然后创建
IntentFilter并调用registerReceiver(BroadcastReceiver, IntentFilter)就成功注册广播接收器了,如下所示
val br: BroadcastReceiver = MyBroadcastReceiver() val filter = IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION).apply { addAction(Intent.ACTION_AIRPLANE_MODE_CHANGED) } registerReceiver(br, filter) - 除了上面的静态注册,还可以直接在Kotlin或Java代码中进行动态注册,而无需在AndroidManifest文件中定义。具体做法是,首先创建一个BroadcastReceiver(或者它的子类)的实例,然后创建
在不需要接收之前注册的广播时,可以使用unregisterReceiver(android.content.BroadcastReceiver)来取消注册广播接收器。此外,如果是通过动态注册的方式注册了广播接收器,还需要在Activity生命周期结束时(onDestroy()方法中)取消注册广播接收器,否则将会导致接收器资源泄露的问题。
发送广播
Android提供三种发送广播的方法,分别是sendBroadcast(Intent)、sendOrderedBroadcast(Intent, String)和LocalBroadcastManager.sendBroadcast
sendBroadcast(Intent)- 发送标准广播,例如
Intent().also { intent -> intent.setAction("com.example.broadcast.MY_NOTIFICATION") intent.putExtra("data", "Notice me senpai!") sendBroadcast(intent) }sendOrderedBroadcast(Intent, String)- 发送有序广播
LocalBroadcastManager.sendBroadcast(Intent)- 发送本地广播,这种广播只会发送给与发送方位于同一应用的广播接收器,而不会发送给其他应用
常用系统广播
- Intent.ACTION_CONNECTIVITY_CHANGE
- 网络状态发生改变
- Intent.ACTION_BATTERY_CHANGED
- 充电状态、电池电量发生变化
- Intent.ACTION_SCREEN_ON
- 屏幕打开
- Intent.ACTION_SCREEN_OFF
- 屏幕关闭
- Intent.ACTION_PACKAGE_INSTALL
- 应用程序开始安装
- Intent.ACTION_BOOT_COMPLETED
- 系统启动完成
- Intent.ACTION_PACKAGE_ADDED
- 应用程序完成安装
- Intent.ACTION_PACKAGE_REMOVED
- 应用程序被移除
- ...