为何Configuration.UI_MODE_NIGHT_YES会自动生效?Android 9设备默认启用深色模式的原因及非动态重建Activity的切换方案
为什么Android 9会默认启用深色模式?
虽然Android 10(API 29)才正式推出系统级深色模式,但你使用的较新版本AppCompat库已经提前支持了日夜主题切换逻辑。如果你的应用主题继承了Theme.MaterialComponents.DayNight或Theme.AppCompat.DayNight这类支持日夜切换的父主题,AppCompat会自动检测当前UI模式来选择对应主题——哪怕是Android 9设备,部分厂商自定义ROM可能带有类夜间模式的设置,或者AppCompat库的默认行为会触发夜间模式判定,最终导致应用加载了themes.xml(night)。
你检测到UI_MODE_NIGHT_YES也印证了这一点:AppCompat已经将应用的UI模式切换为夜间状态,因此才会加载夜间主题。
无需调用setDefaultNightMode()的解决方案
如果你想默认使用themes.xml的浅色主题,同时避免Activity重建,试试下面几种方法:
1. 修改主题继承,使用非DayNight主题
直接把你的主题父类从支持日夜切换的DayNight主题,改成固定的浅色主题。比如在res/values/themes.xml中:
<style name="Theme.YourAppName" parent="Theme.MaterialComponents.Light.DarkActionBar"> <!-- 保留你的其他主题配置 --> </style>
这样主题本身不具备日夜切换能力,自然不会去加载themes.xml(night)的内容,彻底避免夜间模式触发。
2. 在AndroidManifest中强制设置UI模式
在<application>或者<activity>标签里添加android:uiMode="nightNo"属性,应用启动时就会默认使用非夜间模式,且不会导致Activity重建:
<application ... android:uiMode="nightNo" android:theme="@style/Theme.YourAppName"> <!-- 应用组件配置 --> </application>
这个属性会告诉系统应用的默认UI模式是夜间关闭状态,AppCompat会据此加载浅色主题。
3. 通过资源配置禁用AppCompat的日夜模式
创建res/values/config.xml文件,添加以下配置:
<bool name="abc_enable_daynight_mode">false</bool>
这个布尔值是AppCompat库内部用来控制是否启用日夜模式的开关,设置为false后,AppCompat就不会触发夜间主题的切换逻辑了。注意这是AppCompat的内部配置,未来版本可能有变动,但当前版本可以正常生效。
内容的提问来源于stack exchange,提问作者Al Ryan Acain

