使用Java开发Android应用切换主题后Activity闪烁刷新问题求助
问题根源
调用AppCompatDelegate.setDefaultNightMode()时,AppCompat默认会触发当前存活Activity的重建流程,这就是你遇到闪屏、Activity自动刷新的原因。同时你在onCheckedChanged回调中重复调用dark_light.setChecked(),会二次触发开关状态回调,引发重复执行逻辑,导致卡顿。
解决方案
1. Manifest添加配置变更声明
在你AndroidManifest.xml的MainActivity标签中添加configChanges属性,告知系统夜间模式相关的配置变更由应用自行处理,不需要重建Activity:
<activity android:name=".MainActivity" android:configChanges="uiMode|screenLayout|screenSize|smallestScreenSize" android:exported="true"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity>
你原来的application配置无需修改。
2. 优化MainActivity逻辑
去掉冗余的setChecked调用,调整执行顺序避免不必要的性能消耗:
public class MainActivity extends AppCompatActivity implements AdapterView.OnItemSelectedListener { Switch dark_light; SharedPreferences sharedPreferences = null; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); sharedPreferences = getSharedPreferences("night", 0); // 先设置主题再加载布局,避免初始闪屏 Boolean isNightMode = sharedPreferences.getBoolean("night_mode", true); if(isNightMode){ AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES); }else{ AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_NO); } setContentView(R.layout.activity_main); dark_light = findViewById(R.id.dark_light); // 先设置开关状态,再设置监听,避免初始化时触发不必要的回调 dark_light.setChecked(isNightMode); dark_light.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { @Override public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { // 先保存配置再切换主题 SharedPreferences.Editor editor = sharedPreferences.edit(); editor.putBoolean("night_mode", isChecked); editor.apply(); // apply是异步写入,比同步的commit性能更好,不会阻塞主线程 if(isChecked){ AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES); }else{ AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_NO); } } }); } // 可选:如果需要手动更新界面元素,可重写该方法 @Override public void onConfigurationChanged(@NonNull Configuration newConfig) { super.onConfigurationChanged(newConfig); // 此处可手动更新当前界面的颜色、图片等资源,无需重建整个Activity } }
内容的提问来源于stack exchange,提问作者user17300427
相关产品推荐
相关产品推荐

