android - AppCompatDelegate#setDefaultNightMode() 从 API 23 的 SettingsActivity 返回后导致 MainActivity 冻结
问题描述
我已经为我的应用程序实现了一个日/夜主题,并在我的 PreferencesActivity/Fragment 中添加了一个 ListPreference 以在那里进行更改。对于 API 24+,一切正常,但不适用于 API 23(这是我的最低要求)。
问题:当在 Preferences 中选择不同的主题,然后返回 MainActivity 时,它会应用新主题,然后冻结。
我在日志中看到,MainActivity 正在重新创建自己,再次经历生命周期,但在最后一个 onResume() 之后调用 onPause()。
从 MainActivity 启动 PreferencesActivity:
06-02 23:29:17.795 11783-11783/com.package D/MainActivity: onPause()
06-02 23:29:17.815 11783-11783/com.package D/PreferencesActivity: onResume()
06-02 23:29:18.299 11783-11783/com.package D/RosterParentFragment: saving instance state with 2019-06
切换主题:
06-02 23:29:29.853 11783-11783/com.package D/PreferencesFragment: Preference changed with key KEY_DAY_NIGHT_MODE
06-02 23:29:29.856 11783-11783/com.package D/PreferencesActivity: onPause()
06-02 23:29:29.870 11783-11783/com.package D/PreferencesActivity: onResume()
切换回 MainActivity(通过后按或主页 <-):
06-02 23:32:26.209 11783-11783/com.package D/MainActivity: onResume()
06-02 23:32:26.247 11783-11783/com.package D/MainActivity: onPause()
06-02 23:32:26.248 11783-11783/com.package D/RosterParentFragment: saving instance state with 2019-06
06-02 23:32:26.254 11783-11783/com.package D/RosterParentFragment: onCreate()
06-02 23:32:26.254 11783-11783/com.package D/RosterParentFragment: savedInstanceState == Bundle[{android:support:fragments=androidx.fragment.app.FragmentManagerState@9a98da, androidx.lifecycle.BundlableSavedStateRegistry.key=Bundle[{}], SelectedYearMonth=2019-06, android:view_state={2131296460=FragmentPager.SavedState{f01b10b position=113}}}]
06-02 23:32:26.254 11783-11783/com.package D/MainActivity: onCreate()
06-02 23:32:26.266 11783-11783/com.package D/MainActivity: savedInstanceState NOT null
06-02 23:32:26.266 11783-11783/com.package D/MainActivity: got fragment from fragment manager
06-02 23:32:26.268 11783-11783/com.package D/RosterParentFragment: onCreateView()
06-02 23:32:26.353 11783-11783/com.package D/MainActivity: onResume()
06-02 23:32:26.366 11783-11783/com.package D/MainActivity: onPause()
(而这最后一个 onPause() 似乎是罪魁祸首 - 没有为 API 24+ 这样做。)
之后,触摸屏幕会给出一个
W/ViewRootImpl: Dropping event due to no window focus: MotionEvent
警告并离开应用程序(例如主页按钮)给出
Performing pause of activity that is not resumed
适用于 API 24+。有任何想法吗?
class PreferencesFragment : PreferenceFragmentCompat(), SharedPreferences.OnSharedPreferenceChangeListener {
private val dayNightMode: ListPreference by lazy { findPreference<ListPreference>(Preferences.Key.DAY_NIGHT_MODE)!! }
private val dayNightModeEntries = App.instance.applicationContext.resources.getStringArray(R.array.preferences_theme_entries)
private val dayNightModeValues = App.instance.applicationContext.resources.getStringArray(R.array.preferences_theme_values)
override fun onSharedPreferenceChanged(sharedPreferences: SharedPreferences?, key: String?) {
when (key) {
Preferences.Key.DAY_NIGHT_MODE -> {
AppCompatDelegate
.setDefaultNightMode(
Preferences.getCurrentDayNightMode())
}
}
}
override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
setPreferencesFromResource(R.xml.preferences, rootKey)
}
override fun onStart() {
super.onStart()
Preferences.default()
.registerOnSharedPreferenceChangeListener(this)
}
override fun onStop() {
Preferences.default()
.unregisterOnSharedPreferenceChangeListener(this)
super.onStop()
}
}
object Preferences {
object Key {
val DAY_NIGHT_MODE: String = "KEY_DAY_NIGHT_MODE"
}
fun default(): SharedPreferences = PreferenceManager
.getDefaultSharedPreferences(App.instance.applicationContext)
fun getCurrentDayNightMode(): Int {
if (default().getString(Key.DAY_NIGHT_MODE, null) == null) {
// no DayNightMode selected - setting to MODE_NIGHT_FOLLOW_SYSTEM
default().setValue(Key.DAY_NIGHT_MODE, MODE_NIGHT_FOLLOW_SYSTEM.toString())
}
return default().getString(Key.DAY_NIGHT_MODE, null)!!.toInt()
}
fun setCurrentDayNightMode(mode: Int) {
AppCompatDelegate.setDefaultNightMode(mode)
default().setValue(Key.DAY_NIGHT_MODE, mode.toString())
}
}
解决方案
推荐阅读
- python - Django 检索帖子被点赞的时间
- jquery - 在最大化/桌面屏幕上需要帮助
- angular - 选项卡在 Angular 9 的 html 模式下的 ng2-ace-editor 上不起作用
- javascript - 如何使用 Microsoft Graph 将现有电子邮件作为附件添加到新电子邮件
- javascript - 在 Angular 中获取 http://localhost:4200/[object%20Blob] 404(未找到)
- angular - Angular Jest 测试异步代码不是异步的
- python - Anaconda3 和 pip 卸载/安装上的世界银行 WBDATA 引发缓存目录错误
- postgresql - 将 .csv 导入 PostgreSQL 的另一种方法
- sql - 更新查询正在修改所有记录
- django - Django 表单向导:如何手动验证表单