在尝试通过onSaveInstanceState()保留状态时遇到了一个令人沮丧的问题,因此我想提出自己的方案并回答自己的问题以帮助他人。 (代码在Kotlin中,但概念相同)
我有多个片段,用户可以通过屏幕导航来切换。为了记住用户在哪里,我将位置保存在onSaveInstanceState()
override fun onSaveInstanceState(savedInstanceState: Bundle?){
super.onSaveInstanceState(savedInstanceState)
Log.d(TAG, "whereAreWe ${appLocation.name}")
with(savedInstanceState!!){
putInt("whereAreWe", appLocation.ordinal)
putString("questionStatistics", questionStatistics.toString())
}
}
因此,当用户旋转屏幕或从按下主页按钮(在onCreate()中)导航回到应用程序时:
....
if(savedInstanceState == null){
Log.d(TAG, "Opening Dashboard")
appLocation = AppLocation.DASHBOARD
supportFragmentManager.beginTransaction().replace(R.id.fragment_holder, DashboardFragment(), DashboardFragment.TAG).commit()
}
else {
appLocation = AppLocation.values()[savedInstanceState.getInt("whereAreWe")]
Log.d(TAG, "Opening Fragment: ${appLocation.name}")
when (appLocation) {
AppLocation.DASHBOARD -> supportFragmentManager.beginTransaction().replace(R.id.fragment_holder,
supportFragmentManager.findFragmentByTag(DashboardFragment.TAG),
DashboardFragment.TAG).commit()
......
当用户旋转屏幕,记住他们的位置并由应用程序将其导航到适当的片段时,一切工作都很好。
但,当用户按下电话上的主页按钮,然后导航回该应用程序时,onSaveInstanceState()未被调用,并且由于saveInstanceState为空,因此该用户将被强制返回仪表板的主要片段。
我在网上搜寻解决方案,但没有一个方案能真正满足我的要求:它可用于屏幕方向更改,但在按下主屏幕后不。
答案 0 :(得分:3)
事实证明,问题不在于使用哪个Android版本或代码的编写方式,而是在清单文件中。出于某种原因(复制粘贴,默认设置),我的活动标记为noHistory标记为true。
<activity android:name=".MainActivity" android:noHistory="true"></activity>
我不确定为什么在那儿有那个,但那会引起各种各样的问题。我切换到:
<activity android:name=".MainActivity"></activity>
将noHistory标记标记为true可以防止在用户按下主屏幕按钮(应用程序进入后台)时调用onSaveInstanceState(),但仍允许在屏幕方向更改时保存该状态发生了。
我以前从未遇到过这种行为,其他从未遇到过涉及onSaveInstanceState的问题的问题也从未提及过检查此标记的清单文件,因此希望这有助于为其他人澄清任何问题。