用户按下主页按钮时未调用 onSaveInstanceState()
onSaveInstanceState() not being called when user presses home button
我 运行 在尝试通过 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()
......
当用户旋转屏幕时一切正常,他们的位置被记住并且应用程序将他们导航到适当的片段。
但是 当用户按下 phone 上的主页按钮,然后导航回应用程序时,没有调用 onSaveInstanceState(),因为 savedInstanceState 是null,用户将被强制返回主仪表板片段。
我在网上搜索了一个解决方案,但没有真正符合我的方案:它适用于屏幕方向更改,但不按下主屏幕后。
事实证明,问题不在于正在使用哪个 Android 版本,或者代码是如何编写的,问题出在清单文件中。出于某种原因(复制粘贴,默认设置),我的 activity.
标签 noHistory 标记为 true
<activity android:name=".MainActivity" android:noHistory="true"></activity>
我不确定为什么我在那里有它,但它导致了各种各样的问题。我切换到:
<activity android:name=".MainActivity"></activity>
将 noHistory 标记标记为 true 会阻止 onSaveInstanceState() 在用户按下主页按钮(应用程序进入后台)时被调用 但是 仍然允许状态为当屏幕方向发生变化时保存。
我以前从未遇到过这种行为,其他关于未调用 onSaveInstanceState 的问题也从未提到检查清单文件中的此标记,因此希望这有助于为其他人澄清任何问题。
我 运行 在尝试通过 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()
......
当用户旋转屏幕时一切正常,他们的位置被记住并且应用程序将他们导航到适当的片段。
但是 当用户按下 phone 上的主页按钮,然后导航回应用程序时,没有调用 onSaveInstanceState(),因为 savedInstanceState 是null,用户将被强制返回主仪表板片段。
我在网上搜索了一个解决方案,但没有真正符合我的方案:它适用于屏幕方向更改,但不按下主屏幕后。
事实证明,问题不在于正在使用哪个 Android 版本,或者代码是如何编写的,问题出在清单文件中。出于某种原因(复制粘贴,默认设置),我的 activity.
标签 noHistory 标记为 true<activity android:name=".MainActivity" android:noHistory="true"></activity>
我不确定为什么我在那里有它,但它导致了各种各样的问题。我切换到:
<activity android:name=".MainActivity"></activity>
将 noHistory 标记标记为 true 会阻止 onSaveInstanceState() 在用户按下主页按钮(应用程序进入后台)时被调用 但是 仍然允许状态为当屏幕方向发生变化时保存。
我以前从未遇到过这种行为,其他关于未调用 onSaveInstanceState 的问题也从未提到检查清单文件中的此标记,因此希望这有助于为其他人澄清任何问题。