如果状态是由我的类组成的,如何在Android中的方向更改期间保存状态?

got*_*ch4 53 android

我正在研究Android为我的应用程序处理方向更改的方式(我发现它重新开始了方向更改的主要活动.我已经看到你可以覆盖方法

protected void onSaveInstanceState(Bundle outState)
Run Code Online (Sandbox Code Playgroud)

要保存内容,请在onStart中进行操作.问题是我使用自定义适配器查看自定义对象和列表视图.一切都在这些对象的ArrayList中,但我注意到你不能在bundle中放置任意对象!那么如何保存状态呢?

Rah*_*til 137

你有没有尝试过:它的工作,

<activity name= ".YourActivity" android:configChanges="orientation|screenSize"/>
Run Code Online (Sandbox Code Playgroud)

在清单文件?

默认情况下它不起作用,因为当您更改方向时,onCreate将再次调用它并重绘您的视图.

如果你写这个参数不需要在Activity中处理,那么框架将处理其余的事情.如果方向改变,它将保持屏幕或布局的状态.

注意 如果为横向模式使用不同的布局,则通过添加这些参数,将不会调用横向模式的布局.

其他方式另一种方式

  • 一个大胖子-1."也许最讨厌和最广泛滥用的解决方法是通过在Android清单中设置android:configChanges属性来禁用默认的销毁和重新创建行为." [来源](http://www.androiddesignpatterns.com/2013/04/retaining-objects-across-config-changes.html) (37认同)
  • 为什么这不是默认的工作方式?谁希望他们的数据在轮换时丢失? (9认同)
  • 非常感谢,这对我很有帮助! (3认同)
  • @SimonAndréForsberg,文章较新.大多数开发人员都明白我的答案是一个解决方案,如果他们不使用manifest中的参数,他们可以使用诸如`onSaveInstanceState``onRestoreInstanceState`和`onConfigurationChanged`之类的方法.有不同的方法来解决问题,并且所有人都有不同的解决问题的方法. (2认同)

Yon*_*lan 43

编辑:在较新版本的Android和兼容性库中,保留的片段通常是处理在活动销毁/创建过程中保持昂贵的重建数据的最佳方式.正如Dianne所指出的那样,保留非配置数据是为了优化缩略图生成之类的事情,这些事情由于性能原因而很好地保存,但如果需要重做,则对于活动运行并不重要 - 它不能代替正确保存和恢复活动状态.

但是当我在2010年第一次回答这个问题时:
如果你想保留自己的(非视图状态)数据,你实际上可以使用传递任意对象专门用于方向更改onRetainNonConfigurationInstance().查看此Android开发者博客文章.请注意不要在您传递的对象中放置任何视图或其他引用到预旋转的Context/Activity,否则您将阻止这些对象被垃圾收集并最终耗尽内存(这称为上下文泄漏).

  • 请注意,onRetainNonConfigurationInstance()应*仅*用作优化.即使没有发生这种情况,你的应用程序仍然可以正常工作...因为它有*不*保证它会,并且实际上很多情况下它肯定不会被调用.您应该首先通过完整保存的状态机制使您的应用程序正常工作,并且只将此方法实现为优化. (7认同)

hac*_*bod 16

首先,您需要确定应用中的"状态".你还没有说出你实际在做什么,但让我假设对象的ArrayList是用户正在使用的状态.

其次,确定这个州的生命周期实际上是什么.它真的与那项活动有关吗?或者,如果用户说电池电量不足,用户不会丢失,设备将关闭,之后他们会返回您的应用程序?如果是前者,onSaveInstanceState()是正确的; 如果是后者,你将要保存到持久存储中onPause().

对于onSaveInstanceState()自定义对象,关键是实现Parcelable接口.这涉及在Parcelable上实现方法,以及在类中创建静态CREATOR对象.这是典型的简单Parcelable类的代码:

https://android.googlesource.com/platform/frameworks/base/+/refs/heads/master/core/java/android/content/ComponentName.java

关键功能是Parcelable实现:

https://android.googlesource.com/platform/frameworks/base/+/refs/heads/master/core/java/android/content/ComponentName.java#317

和CREATOR静态类:

https://android.googlesource.com/platform/frameworks/base/+/refs/heads/master/core/java/android/content/ComponentName.java#355

(静态writeToParcel()并且readFromParcel()只是为该类完成的便利而不是必需的.)

现在您已经拥有了它,您可以将整个对象的ArrayList放入已保存的状态Bundle中Bundle.putParcelableArrayList:

http://developer.android.com/reference/android/os/Bundle.html#putParcelableArrayList(java.lang.String,java.util.ArrayList)

Activity.onCreate(),检查是否有savedState Bundle,如果是,请尝试从中检索ArrayList并在找到时使用它,为用于显示它的新活动创建新的适配器和列表视图.