广播接收器 → 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 老项目迁移系列,持续更新中。

相关推荐
圆山猫18 小时前
[Virtualization](四):Linux KVM/RISC-V 的 vCPU 运行路径
java·linux·risc-v
城管不管19 小时前
ReAct、Plan-and-Execute、Reflection 三大智能 Agent 范式核心区别
java·人工智能·算法·spring·ai·动态规划
IT小白杨19 小时前
从环境制备到自动化工作流:多账号运营的工程化架构拆解
java·经验分享·自动化·安全架构·指纹浏览器
summerkissyou198719 小时前
Android - 摄像头 - hal - 开发教程,例子,常见问题,分析方法,解决方案
android
豆瓣鸡20 小时前
算法日记 - Day3
java·开发语言·算法
萧瑟余晖20 小时前
Java深入解析篇九之NIO详解
java·网络·nio
summerkissyou198720 小时前
Android 16 架构图
android
The Chosen One98520 小时前
高进度算法模板速记(待完善)
java·前端·算法
神龙天舞200121 小时前
MySQL 备库为什么会延迟好几个小时
android·数据库·mysql
极光代码工作室1 天前
基于SpringBoot的课程预约系统
java·springboot·web开发·后端开发