Android应用杀死重启后已设置深色主题失效问题咨询
问题根因定位
- 自定义
MigotoApplication中未初始化SharedPreferences就直接调用其方法,触发空指针导致主题设置逻辑直接失效,App重启后默认走系统浅色主题 - 主题确认按钮的存储逻辑加了不必要的
if (mPreferences.contains(SP_THEME_KEY))判断,用户首次设置深色主题时,因为SP里还不存在对应key,根本不会执行存储逻辑,重启后自然读不到深色配置 - 逻辑冗余:你同时在Application层设置
AppCompatDelegate全局夜间模式,又在每个Activity里单独setTheme,两套逻辑容易发生冲突
修复方案
第一步:修复Application类的初始化问题
补全SharedPreferences初始化逻辑:
public class MigotoApplication extends Application { private final String SP_THEME_KEY = "sp_theme_key"; private SharedPreferences mPreferences; private String spFileName = "settingsSpFile"; private int theme; @Override public void onCreate() { super.onCreate(); // 补全SharedPreferences初始化逻辑 mPreferences = getSharedPreferences(spFileName, MODE_PRIVATE); if (mPreferences.contains(SP_THEME_KEY)) { theme = mPreferences.getInt(SP_THEME_KEY, 2); switch(theme){ case 1: //dark AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES); break; case 2: //light AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_NO); break; } } else { theme = 2; SharedPreferences.Editor spEditor = mPreferences.edit(); spEditor.putInt(SP_THEME_KEY, theme); spEditor.apply(); AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_NO); } } }
第二步:移除确认按钮存储逻辑的多余判断
删除contains判断,无论key是否存在都直接写入配置:
bottomSheetView.findViewById(R.id.settingsGeneral_changeTheme_btnOK).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { switch (tempTheme) { case 1: theme = 1; SharedPreferences.Editor spEditor = mPreferences.edit(); spEditor.putInt(SP_THEME_KEY, theme); spEditor.apply(); AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES); break; case 2: theme = 2; SharedPreferences.Editor spEditor = mPreferences.edit(); spEditor.putInt(SP_THEME_KEY, theme); spEditor.apply(); AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_NO); break; } bottomSheetDialog.dismiss(); } });
第三步:简化Activity层主题逻辑
如果你的darkTheme、appTheme都继承自Theme.MaterialComponents.DayNight系列主题,已经在Application层全局设置了AppCompatDelegate的情况下,不需要再在每个Activity里单独写setTheme逻辑。如果不想修改主题继承关系,保留Activity里的setTheme逻辑即可,需确保所有Activity都统一执行顺序:先读SP设置主题,再调用super.onCreate,最后执行setContentView。
内容的提问来源于stack exchange,提问作者Croissant
相关产品推荐
相关产品推荐

