Skip to content

一、广播类型

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() // 终止广播
}

七、最佳实践

  1. 最小化接收器运行时间onReceive() 在主线程执行,避免耗时操作。
  2. 使用权限:发送敏感广播时声明权限:
    xml
    <uses-permission android:name="com.example.PERMISSION" />
    kotlin
    sendBroadcast(intent, "com.example.PERMISSION")
  3. 避免内存泄漏:动态注册的接收器必须及时取消注册。
  4. 适配 Android 版本:注意不同系统版本对广播的限制。

通过合理使用广播机制,可以实现灵活的组件通信,但需注意系统限制和性能优化。