广播接收器 → Flow + Lifecycle

广播接收器 → Flow + Lifecycle

老写法(Java + BroadcastReceiver)

java 复制代码
private BroadcastReceiver batteryReceiver = new BroadcastReceiver() {
    @Override
    public void onReceive(Context context, Intent intent) {
        int level = intent.getIntExtra(BatteryManager.EXTRA_LEVEL, 0);
        tvBattery.setText("电量:" + level + "%");
    }
};

@Override
protected void onResume() {
    super.onResume();
    IntentFilter filter = new IntentFilter(Intent.ACTION_BATTERY_CHANGED);
    registerReceiver(batteryReceiver, filter);
}

@Override
protected void onPause() {
    super.onPause();
    unregisterReceiver(batteryReceiver);
}

问题在哪里

register/unregister 必须在正确的生命周期成对调用,时机一错就崩。每个广播接收器都要写注册逻辑和解注册逻辑,多个广播到处都是散落的 IntentFilter。

新写法(Flow + Lifecycle)

kotlin 复制代码
// 封装为 Flow
fun batteryLevelFlow(context: Context): Flow<Int> = callbackFlow {
    val receiver = object : BroadcastReceiver() {
        override fun onReceive(context: Context, intent: Intent) {
            val level = intent.getIntExtra(BatteryManager.EXTRA_LEVEL, 0)
            trySend(level)
        }
    }
    context.registerReceiver(receiver, IntentFilter(Intent.ACTION_BATTERY_CHANGED))
    awaitClose { context.unregisterReceiver(receiver) }
}

// 使用 --- 自动绑定生命周期
lifecycleScope.launch {
    repeatOnLifecycle(Lifecycle.State.STARTED) {
        batteryLevelFlow(this@MainActivity).collect { level ->
            tvBattery.text = "电量:$level%"
        }
    }
}

一句话注意

callbackFlow 内部 registerReceiverawaitCloseunregisterReceiver,生命周期完全自动绑定,不需要手动 register/unregister。repeatOnLifecycle(STARTED) 确保前台才收集、后台自动取消,和 onResume/onPause 的注册时机语义一致。

Intent.ACTION_BATTERY_CHANGED 这种粘性广播不能用 context.registerReceiver 注册结果返回 null 的问题------因为它是粘性广播,即使是首次注册也会立刻收到回调,没有问题。但注意这个广播不能通过 manifest 静态注册,只能动态注册。


Java Android 老项目迁移系列,持续更新中。

相关推荐
plainGeekDev1 小时前
EventBus → SharedFlow
android·java·kotlin
带刺的坐椅1 小时前
Spring Boot → Solon 注解迁移实战指南:一张对照表说清楚
java·springboot·web·solon
用户3721574261352 小时前
Java 将一个 PPT 文档拆分为多个文件
java
人活一口气17 小时前
Spring Boot与AIGC的完美结合:从零搭建智能内容生成平台
java·spring boot·aigc
像我这样帅的人丶你还19 小时前
Java 后端详解(三):全局异常处理与 JPA 数据库映射
java·后端
NE_STOP19 小时前
vibe Coding -- 小项目实战
java
未秃头的程序猿1 天前
Java 26正式发布!这3个新特性,让代码量直接减半
java·后端·面试
37手游移动客户端团队1 天前
招聘-高级安卓开发工程师
android·客户端
用户298698530141 天前
Word 文档文本查找与替换的 Java 实现方案
java·后端