Android:在屏幕方向改变时保存应用程序状态

3
在发布这个问题之前,我看过以下链接: http://www.devx.com/wireless/Article/40792/1954 使用Save Instance State保存Android Activity状态 http://www.gitshah.com/2011/03/how-to-handle-screen-orientation_28.html 如果状态由我的类组成,如何在Android方向更改期间保存状态? 我不知道该如何重写以下函数:
@Override
    public Object onRetainNonConfigurationInstance() {
        return someExpensiveObject;
    }

在我的应用程序中,我有一个布局,其中一个edittext可见,当第一个editext的数据验证为真时,其他editext将变得可见。我将所有其他editextes和textviews的可见性设置为false,并在验证后使它们可见。
因此,在我的活动中,如果屏幕方向发生变化,则所有具有android:visibility="false"的项目都会变得不可见。
我还了解到,当我们的活动屏幕方向发生变化时,它会调用onStop(),然后调用onDestroy(),然后通过调用onCreate()再次启动新的活动。
这是原因...但我不知道如何解决它...
您可以查看我的应用程序的截图:
在这个图片中,所有字段都被加载了,而在另一张图片中,当屏幕方向改变为横向时,它们全部消失了。
任何教程或代码片段的链接都会受到高度赞赏。
当显示进度对话框并尝试更改屏幕方向时,我的应用程序崩溃。如何处理?谢谢!

一个很好的教程,介绍如何使用保存的实例状态包来处理活动状态,请查看http://www.quicktips.in/handling-activity-state-using-saved-instance-state-bundle/。 - Deepak Swami
3个回答

7
如果你的两个屏幕有相同的布局,那么就不需要这样做,只需在Activity节点中的manifest中添加以下行:
android:configChanges="keyboardHidden|orientation"

对于 Android 3.2(API 等级 13)及更高版本:

android:configChanges="keyboardHidden|orientation|screenSize"

因为设备在横屏和竖屏模式之间切换时,"屏幕尺寸"也会改变。
参考文档:http://developer.android.com/guide/topics/manifest/activity-element.html

谢谢您的回复,它对我有用...那么为什么要使用onRetainNonConfigurationInstance()函数呢? - Shruti
@Shruti 如果你有不同的布局文件,那么在布局更改时保存数据是必要的,因为在这种情况下布局会交换。 - ingsaurabh
好的,当有人在进度条显示时更改方向,我应该如何防止应用程序崩溃? - Shruti
一旦您使用上述方法,活动将不会重新启动,因此进度条也不会关闭,然后您的应用程序将不会崩溃。 - ingsaurabh
1
我想你需要使用 onSaveInstanceState(Bundle) 来保存每个视图的可见性。 - Oleg Vaskevich

1

还有另一种可能性,可以使用onConfigurationChanged(Configuration newConfig)来保持状态不变,即使在方向更改时也是如此。

当您的活动正在运行时,系统在设备配置更改时调用此函数。请注意,只有在您选择了要使用configChanges属性处理的配置时,才会调用此函数。如果发生任何未被该属性选择报告的配置更改,则系统将停止并重新启动活动(以便使用新配置启动它),而不是报告它。

在调用此函数时,您的资源对象将已更新为返回与新配置匹配的资源值。


0

有两种方法可以做到这一点,第一种是在AndroidManifest.xml文件中。您可以将此添加到活动的标记中。此文档将为您提供深入的解释,但简单地说,它使用这些值并告诉活动在这些值之一更改时不要重新启动。

android:configChanges="keyboardHidden|orientation|screenSize|screenLayout"

第二种方法是:重写onSaveInstanceStateonRestoreInstanceState。这种方法需要更多的努力,但可以说更好。 onSaveInstanceState在活动被杀死之前保存开发人员手动设置的值,并且onRestoreInstanceStateonStart()之后恢复该信息请参阅官方文档以获得更深入的了解。您不必实现onRestoreInstanceState,但那将涉及将该代码粘贴到onCreate()中。

在下面的示例代码中,我保存了2个int值,即下拉列表的当前位置和单选按钮。

 @Override
    public void onSaveInstanceState(@NonNull Bundle savedInstanceState) {
        spinPosition = options.getSelectedItemPosition();
        savedInstanceState.putInt(Constants.KEY, spinPosition);
        savedInstanceState.putInt(Constants.KEY_RADIO, radioPosition);
        super.onSaveInstanceState(savedInstanceState);

    }

    // And we restore those values with `getInt`, then we can pass those stored values into the spinner and radio button group, for example, to select the same values that we saved earlier. 

    @Override
    public void onRestoreInstanceState(@NotNull Bundle savedInstanceState) {
        spinPosition = savedInstanceState.getInt(Constants.KEY);
        radioPosition = savedInstanceState.getInt(Constants.KEY_RADIO);
        options.setSelection(spinPosition, true);
        type.check(radioPosition);
        super.onRestoreInstanceState(savedInstanceState);
    }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接