日夜切换按钮文字颜色偶发异常排查记录

悬浮窗场景下日夜主题切换后,cancel按钮文字色偶发异常。不是没调刷新,不是资源写错,是selector解析链路的时序抖动。

问题

悬浮窗弹窗里做日夜主题切换,confirm按钮颜色正常,cancel按钮在白天模式下偶发显示夜间白色。

关键特征:偶发,不是每次都能复现。

排查

先列4个假设,埋日志逐个排除:

  1. uiMode没切到白天 → uiMode=16确实出现
  2. confirm和cancel刷新链路不同 → ,链路一致
  3. cancel刷新后取到的色值跟资源不一致 → currentTextColor有时跟text_color_normal对不上
  4. 刷新后被其他逻辑覆盖 → ,前后一致

为什么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状态颜色正确

排障清单

遇到"主题切换后颜色偶发异常”,按顺序查:

  1. 确认uiMode是否正确
  2. 对比currentTextColor和期望资源色值
  3. 检查enabled/disabled状态
  4. 确认没有末尾覆盖
  5. 审查是否依赖"间接selector+手动刷新"

先拿运行时证据,再做最小修复。别猜,看日志。

使用 Hugo 构建
主题 StackJimmy 设计