【发布时间】:2018-11-17 23:48:37
【问题描述】:
运行Android P,使用androidx 1.0.0 (minSdkVersion 17)。从我的MainActivity 打开我的PreferenceActivity。在那里我更改了 UI 主题,并重新创建了活动以获取更改:
AppCompatDelegate.setDefaultNightMode(nightMode);
recreate();
更新主题后,返回MainActivity。那里的主题已成功更新。然后我重新打开PreferenceActivity 并更改主题再次。
到目前为止一切顺利!
最后,我再次回到MainActivity。主题未更新,重复上述步骤也不会更新!
因此,重现的步骤似乎是:
- 从活动 A,打开活动 B。
- 在 B 中,拨打
AppCompatDelegate.setDefaultNightMode(MODE_NIGHT_YES),然后拨打recreate()。主题已更新! - 返回 A。主题更新!
- 再次打开活动 B。
- 在 B 中,拨打
AppCompatDelegate.setDefaultNightMode(MODE_NIGHT_NO),然后拨打recreate()。主题已更新! - 返回 A。主题已未更新,如果重复步骤 3-6,将未更新!
我尝试在从PreferenceActivity 返回时调用recreate(),但是当库确实对主题更改做出反应时,这会产生另一个问题:
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
if (...) {
recreate();
} else {
super.onActivityResult(requestCode, resultCode, data);
}
}
当库对更新的主题没有反应时,这有效。否则活动会重新创建两次(调试时可能更多),这会降低性能等:
D/MainActivity: onActivityResult(): instance 1
D/MainActivity: onResume(): instance 1
D/MainActivity: onPause(): instance 1
D/MainActivity: onDestroy(): instance 1
D/MainActivity: onCreate(): instance 2
D/MainActivity: onResume(): instance 2
D/MainActivity: onPause(): instance 2
D/MainActivity: onDestroy(): instance 2
D/MainActivity: onCreate(): instance 3
D/MainActivity: onResume(): instance 3
问:setDefaultNightMode() API 发生了什么?更重要的是,我怎样才能成功更新所有正在运行的活动,而不会有多次重新创建它们的风险?
更新
这里有一个演示该问题的示例项目:https://issuetracker.google.com/issues/119757688
【问题讨论】:
-
有什么解决办法吗?我也遇到了同样的问题。
-
当然。你看到我的回答了吗?
-
其实我在其他地方发现了这个问题(WebView bug);见this answer。
-
有趣。很明显,切换夜间模式仍然容易出错。
-
示例项目不会为我运行,它说主题是错误的。我认为您在项目的 res 中遗漏了文件。