Repository navigation
fix(android): 登录轮询看门狗 + 趋势峰值 dayLabel 崩溃修复(真机 QA 发现) - #27
Qiyuanqiii wants to merge 3 commits into
Conversation
There was a problem hiding this comment.
一句话总结
本次 PR 修复了 Android 版登录轮询的看门狗机制(防止回调丢失导致永久卡死)以及趋势图 dayLabel 的日期解析崩溃问题,改动聚焦且方向正确。
🔴 红线 / 严重问题
未发现触碰红线的问题。
🟡 建议改进
-
TokenLoginWebView.kt:167-172- 看门狗超时时间硬编码postDelayed({ if (gen == checkGeneration) isChecking = false }, 5000)和postDelayed({ if (gen == validateGeneration) isValidating = false }, 90000)中的 5000ms 和 90000ms 是魔法数字,建议提取为具名常量(如CHECK_TIMEOUT_MS、VALIDATE_TIMEOUT_MS),便于维护和调整。
-
TokenLoginWebView.kt:167-172- 看门狗回调未取消postDelayed的回调在页面销毁时不会自动取消,若 WebView 被销毁但 Timer 仍在运行,可能造成内存泄漏或空指针。建议在onDestroy()或destroy()中调用removeCallbacks清理。
-
TokenLoginWebView.kt:167-172- 看门狗与轮询周期耦合- 注释提到"下一个轮询周期(1.5s)会重试",但 5 秒看门狗超时意味着最多可能等待 5 秒 + 1.5 秒轮询间隔 = 6.5 秒才能重试。建议确认这个延迟是否可接受,或考虑在看门狗触发时立即触发下一次轮询。
🔵 小问题 / 风格
-
TokenLoginWebView.kt:167-172- 注释风格不一致- 新增注释使用
// 注意:和// 看门狗代数:开头,与文件中其他///注释风格不一致。建议统一使用///或保持一致的注释风格。
- 新增注释使用
-
dayLabel函数 - 日期解析逻辑可简化dayOnly分支中cal.set(Calendar.DAY_OF_MONTH, dayOnly)后直接使用cal.get(Calendar.MONTH),但Calendar.getInstance()默认是当前日期,直接设置 DAY_OF_MONTH 可能产生跨月问题(如当前是 8 月 31 日,设置 DAY_OF_MONTH=16 会得到 8 月 16 日,但若当前是 9 月 1 日,设置 DAY_OF_MONTH=16 会得到 9 月 16 日)。建议明确设置cal.set(Calendar.MONTH, ...)或使用LocalDate替代。
-
TokenLoginWebView.kt:167-172- 字段声明顺序- 将状态字段移到
init之前是正确做法,但pollTimer等字段与popupCloseButton之间缺少空行分隔,建议增加空行提高可读性。
- 将状态字段移到
审查结论
改动方向正确,修复了真机 QA 发现的两个实际问题(回调丢失导致轮询卡死、日期解析崩溃)。建议合并前处理以下事项:
- 提取看门狗超时时间为具名常量
- 补充 WebView 销毁时的回调清理逻辑
- 确认
dayLabel中Calendar跨月边界场景的处理
其余改动符合仓库规范,未触碰红线。
There was a problem hiding this comment.
一句话总结
该 PR 修复了 Android 端两个真机 QA 发现的问题:登录轮询看门狗机制防止回调丢失导致永久卡死,以及趋势图 dayLabel 对纯数字日期 key 的解析崩溃。
🔴 红线 / 严重问题
未发现触碰红线的问题。改动仅涉及 Android 端(android/ 目录),符合移动端红线 11-13 的约束:零第三方依赖、核心逻辑在 :core 模块、未改动 Token 存储方式。
🟡 建议改进
-
android/.../TokenLoginWebView.kt:240— 看门狗复位逻辑存在竞态窗口
postDelayed({ if (gen == checkGeneration) isChecking = false }, 5000)中,如果回调在 5 秒内正常返回,isChecking已被置为false,但checkGeneration未递增。若此时恰好有新的轮询周期开始(1.5s 间隔),gen仍等于checkGeneration,5 秒后看门狗会错误地将isChecking复位为false,而此时可能正处于新的检查中。建议在回调正常返回时也递增checkGeneration,或在看门狗回调中增加isChecking状态判断。 -
android/.../TokenLoginWebView.kt:277— validateGeneration 看门狗 90 秒超时可能不够
注释提到"校验链路极端情况下最长约 90 秒",但看门狗恰好设为 90 秒。如果网络极端慢或执行器队列积压,可能刚好超过 90 秒导致误复位。建议将超时设为 100-120 秒,留出安全余量。 -
android/.../dayLabel.kt:411-416— 纯数字 key 的月份处理逻辑
cal.set(Calendar.DAY_OF_MONTH, dayOnly)只设置了日,没有设置月份。Calendar.getInstance()默认是当前月份,如果数据是历史月份(如查看上月趋势),会显示错误的月份。建议从dailyEntries的上下文获取正确的月份,或考虑传入月份参数。
🔵 小问题 / 风格
-
android/.../TokenLoginWebView.kt:160-168— 字段声明位置注释过长
字段声明前的注释块有 4 行,解释了为什么字段要放在 init 之前。建议精简为 1-2 行,或在类头部统一说明,避免代码可读性下降。 -
android/.../dayLabel.kt:411— 魔法数字 "16" 示例
注释中"16"的示例很好,但建议同时说明"2026-08-16"格式的兼容性来源(是旧版本遗留还是新格式),方便后续维护。
审查结论
改动方向正确,针对真机 QA 发现的两个问题给出了合理的修复方案:
- 看门狗机制有效解决了回调丢失导致的轮询卡死问题,代数(generation)方案设计合理
- dayLabel 的兼容处理避免了 ParseException 崩溃
建议合并前重点确认:
- 看门狗复位逻辑的竞态窗口(建议改进第 1 点)
- dayLabel 的月份上下文问题(建议改进第 3 点)
- 本地运行
cd android && ./gradlew :core:test确认核心单测通过
整体质量良好,修复方案务实,无红线问题,可以合入。
描述
真机 QA(#16)连续发现的第二个、第三个崩溃,同批修复:
1. 登录轮询被丢失的回调永久卡死(状态冻结在「尚未就绪」)
userToken({"value":"<64字符 Bearer>"}结构),但 App 状态永远停在「尚未就绪,等待登录完成…」;evaluateJavascript回调在页面导航期间可能被丢弃 →isChecking永久为 true → 后续轮询全部早退;checkToken/validate引入代数(generation)+postDelayed看门狗(5s / 90s)——回调丢失时自动复位,下一轮询周期(1.5s)重试;过期回调按代数丢弃,避免串扰。2. 登录成功后主页趋势图崩溃(ParseException)
dailyEntries返回的 key 是「日」数字("16",供图表坐标标签),而峰值标签dayLabel用yyyy-MM-dd解析它(A3 遗留,首次真机有数据才暴露);dayLabel兼容日数字 key(按当月渲染「8月16日」)与完整日期 key。附带说明
tokenCandidates的unwrap()已正确处理新版{"value":…}结构(真机 + CDP 同源验证通过:unwrap 后的候选对/users/current返回 code 0)。验证
关联
变更类型
边界检查