一、广播类型
1. 按发送方式分类
- 标准广播(Normal Broadcast):完全异步,所有接收器同时接收,无法被拦截。
- 有序广播(Ordered Broadcast):同步执行,接收器按优先级顺序处理,可终止传播。
2. 按作用范围分类
- 全局广播:可被任何应用接收(需权限控制)。
- 本地广播:仅限应用内部通信,更安全高效(通过
LocalBroadcastManager
实现,但已弃用,推荐替代方案如LiveData
)。
3. 按注册方式分类
- 动态注册:代码中注册,生命周期与组件(如 Activity)绑定。
- 静态注册:在
AndroidManifest.xml
中声明,应用未启动时也能接收(受系统限制,如 Android 8.0+ 对隐式广播的限制)。
二、核心组件
1. BroadcastReceiver
- 负责接收并处理广播消息。
- 需重写
onReceive(context: Context?, intent: Intent?)
方法。
2. Intent
- 携带广播的**动作(Action)**和附加数据。
- 通过
IntentFilter
指定接收器关注的 Action。
三、动态注册广播示例
1. 监听系统广播(以充电状态变化为例)
kotlin
class MainActivity : AppCompatActivity() {
private lateinit var chargingReceiver: BroadcastReceiver
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
// 创建接收器
chargingReceiver = object : BroadcastReceiver() {
override fun onReceive(context: Context?, intent: Intent?) {
when (intent?.action) {
Intent.ACTION_POWER_CONNECTED -> {
Toast.makeText(context, "充电已连接", Toast.LENGTH_SHORT).show()
}
Intent.ACTION_POWER_DISCONNECTED -> {
Toast.makeText(context, "充电已断开", Toast.LENGTH_SHORT).show()
}
}
}
}
// 注册接收器
val filter = IntentFilter().apply {
addAction(Intent.ACTION_POWER_CONNECTED)
addAction(Intent.ACTION_POWER_DISCONNECTED)
}
registerReceiver(chargingReceiver, filter)
}
override fun onDestroy() {
super.onDestroy()
// 必须取消注册,防止内存泄漏
unregisterReceiver(chargingReceiver)
}
}
2. 发送自定义广播
kotlin
// 发送标准广播
val intent = Intent("com.example.MY_CUSTOM_ACTION").apply {
putExtra("data", "Hello from broadcast!")
}
sendBroadcast(intent)
// 发送有序广播
sendOrderedBroadcast(intent, null)
四、静态注册广播示例
1. 创建接收器类
kotlin
class MyReceiver : BroadcastReceiver() {
override fun onReceive(context: Context, intent: Intent) {
val data = intent.getStringExtra("data")
Toast.makeText(context, "收到静态广播: $data", Toast.LENGTH_SHORT).show()
}
}
2. 在 AndroidManifest.xml
中声明
xml
<receiver
android:name=".MyReceiver"
android:enabled="true"
android:exported="true">
<intent-filter>
<action android:name="com.example.MY_CUSTOM_ACTION" />
</intent-filter>
</receiver>
3. 注意事项(Android 8.0+)
- 限制隐式广播:静态注册无法接收大多数隐式广播(非应用专属 Action)。
- 解决方案:
- 使用动态注册。
- 指定包名发送显式广播:kotlin
val intent = Intent("com.example.MY_CUSTOM_ACTION").apply { setPackage("com.example.myapp") // 指定目标包名 putExtra("data", "Explicit broadcast") } sendBroadcast(intent)
五、本地广播(已弃用,仅供参考)
1. 使用 LocalBroadcastManager
kotlin
// 注册接收器
val localReceiver = object : BroadcastReceiver() {
override fun onReceive(context: Context?, intent: Intent?) {
Toast.makeText(context, "收到本地广播", Toast.LENGTH_SHORT).show()
}
}
LocalBroadcastManager.getInstance(this).registerReceiver(
localReceiver,
IntentFilter("com.example.LOCAL_ACTION")
)
// 发送本地广播
val intent = Intent("com.example.LOCAL_ACTION")
LocalBroadcastManager.getInstance(this).sendBroadcast(intent)
// 取消注册
LocalBroadcastManager.getInstance(this).unregisterReceiver(localReceiver)
2. 替代方案(推荐)
LiveData
:通过观察数据变化实现组件通信。EventBus
:第三方库简化事件传递。RxJava
:响应式编程实现消息传递。
六、有序广播控制
1. 设置优先级
xml
<intent-filter android:priority="100">
<action android:name="com.example.ORDERED_ACTION" />
</intent-filter>
2. 终止广播传播
kotlin
override fun onReceive(context: Context?, intent: Intent?) {
// 处理逻辑...
abortBroadcast() // 终止广播
}
七、最佳实践
- 最小化接收器运行时间:
onReceive()
在主线程执行,避免耗时操作。 - 使用权限:发送敏感广播时声明权限:xml
<uses-permission android:name="com.example.PERMISSION" />
kotlinsendBroadcast(intent, "com.example.PERMISSION")
- 避免内存泄漏:动态注册的接收器必须及时取消注册。
- 适配 Android 版本:注意不同系统版本对广播的限制。
通过合理使用广播机制,可以实现灵活的组件通信,但需注意系统限制和性能优化。