跳到主要内容

BroadcastReceiver 广播机制

问题

Android 广播机制是什么?静态注册和动态注册有什么区别?

答案

1. 广播类型

类型描述接收顺序
标准广播异步发送,几乎同时到达所有接收者无序
有序广播按优先级逐个传递,可拦截按 priority
本地广播仅应用内传播(已废弃)
粘性广播发送后保留,新注册者可收到(已废弃)

2. 动态注册(推荐)

class MyActivity : AppCompatActivity() {

private val networkReceiver = object : BroadcastReceiver() {
override fun onReceive(context: Context, intent: Intent) {
val isConnected = intent.getBooleanExtra(
ConnectivityManager.EXTRA_NO_CONNECTIVITY, false
)
updateNetworkStatus(!isConnected)
}
}

override fun onStart() {
super.onStart()
val filter = IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION)
// Android 14+ 需要指定 RECEIVER_NOT_EXPORTED
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
registerReceiver(networkReceiver, filter, RECEIVER_NOT_EXPORTED)
} else {
registerReceiver(networkReceiver, filter)
}
}

override fun onStop() {
super.onStop()
unregisterReceiver(networkReceiver) // ⚠️ 必须注销,否则内存泄漏
}
}

3. 静态注册

<!-- AndroidManifest.xml -->
<receiver
android:name=".BootReceiver"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
class BootReceiver : BroadcastReceiver() {
override fun onReceive(context: Context, intent: Intent) {
if (intent.action == Intent.ACTION_BOOT_COMPLETED) {
// 开机后启动 WorkManager 任务
WorkManager.getInstance(context).enqueue(syncWork)
}
}
}
Android 8.0+ 静态广播限制

从 Android 8.0 开始,大部分隐式广播不能通过静态注册接收。仍可静态注册的:

  • BOOT_COMPLETED(开机广播)
  • LOCALE_CHANGED(语言切换)
  • MY_PACKAGE_REPLACED(应用更新)
  • 自定义显式广播

其他广播必须使用动态注册

4. 发送广播

// 标准广播
val intent = Intent("com.example.MY_ACTION").apply {
putExtra("data", "hello")
setPackage(packageName) // Android 8.0+ 显式指定包名
}
sendBroadcast(intent)

// 有序广播
sendOrderedBroadcast(intent, null)

// 应用内通信 —— 推荐替代方案
// LiveData / StateFlow / EventBus 而非 LocalBroadcastManager(已废弃)

5. 现代替代方案

场景传统方案现代方案
应用内事件通信LocalBroadcastManagerSharedFlow / EventBus
系统事件监听BroadcastReceiver仍使用 BroadcastReceiver
数据变化通知BroadcastReceiverLiveData / StateFlow
后台事件触发静态 BroadcastReceiverWorkManager

常见面试问题

Q1: 动态注册和静态注册的区别?

答案

特性动态注册静态注册
注册方式代码中 registerReceiverAndroidManifest.xml
生命周期随注册组件(需手动注销)随应用安装
接收时机注册后到注销前应用安装后始终可接收
Android 8.0+不受限大部分隐式广播被限制
优先级相同 action 时动态 > 静态

Q2: onReceive 中能执行耗时操作吗?

答案

不能onReceive 运行在主线程,且有 10 秒超时限制(有序广播),超时会 ANR。

override fun onReceive(context: Context, intent: Intent) {
// ❌ 不能做耗时操作
// ✅ 启动 WorkManager 或前台 Service 处理
val work = OneTimeWorkRequestBuilder<SyncWorker>().build()
WorkManager.getInstance(context).enqueue(work)
}

同时 onReceive 执行完后 BroadcastReceiver 实例就会被销毁,不能在其中启动异步任务(如线程、协程),因为进程可能被系统回收。

相关链接