问题
悬浮窗弹窗里做日夜主题切换,confirm按钮颜色正常,cancel按钮在白天模式下偶发显示夜间白色。
关键特征:偶发,不是每次都能复现。
排查
先列4个假设,埋日志逐个排除:
uiMode没切到白天 → 否,uiMode=16确实出现- confirm和cancel刷新链路不同 → 否,链路一致
- cancel刷新后取到的色值跟资源不一致 → 是,
currentTextColor有时跟text_color_normal对不上 - 刷新后被其他逻辑覆盖 → 否,前后一致
为什么confirm没事,cancel有事?
两个按钮的色资源策略不同:
- confirm用
*_normal_h/*_disable_h(高亮色),昼夜差异小 - cancel用
*_normal/*_disable(默认色),白天黑、夜间白,差异大
confirm不是没问题,是问题藏得更深。
根因
同一轮刷新里,mContext解析出来的text_color_normal已经是白天黑值,但cancel按钮内部的enabledColor还是夜间白值。
“配置已经更新"和"按钮内部色表同步完成"之间存在时序窗口。正常Activity重建不会触发,但悬浮窗+手动onConfigurationChanged+非重建这条路把它暴露出来了。
修复
不依赖间接selector查找,直接用资源引用+手动构建ColorStateList:
val defaultColors = ColorStateList(
arrayOf(intArrayOf(-android.R.attr.state_enabled), intArrayOf()),
intArrayOf(disableColor, normalColor)
)
绕开不稳定链路,确定性地拿到当前主题下的色值。
复测
多轮夜→昼→夜切换:
- cancel白天稳定黑色
- 夜间稳定白色
- disabled状态颜色正确
排障清单
遇到"主题切换后颜色偶发异常”,按顺序查:
- 确认
uiMode是否正确 - 对比
currentTextColor和期望资源色值 - 检查enabled/disabled状态
- 确认没有末尾覆盖
- 审查是否依赖"间接selector+手动刷新"
先拿运行时证据,再做最小修复。别猜,看日志。