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

我正在考虑Android处理方向改变的方式(我发现它重新启动了方向改变的主要活动,我已经看到你可以覆盖方法

protected void onSaveInstanceState(Bundle outState) 

要保存的东西,然后在onStart。 问题是我有自定义对象和使用自定义适配器的列表视图。 一切都在这些对象的ArrayList中,但是我注意到,你不能把任意对象放在包中! 那么如何保存状态呢?

编辑:在Android的新版本和兼容性库, 保留的片段通常是最好的方式来处理在整个活动销毁/创build保持昂贵到重新创build数据。 正如Dianne所指出的那样,保留非configuration数据是为了优化诸如缩略图生成之类的东西,因为性能的原因,这些数据可以很好地保存,但是如果需要重做,对于您的活动function并不重要 – 它不能替代妥善保存和恢复活动状态。

但是当我在2010年第一次回答这个问题时,
如果你想保留你自己的(非视图状态)数据,你实际上可以使用onRetainNonConfigurationInstance()来传递一个专门用于方向改变的任意对象。 看到这个Android开发者博客文章 。 只要注意不要在传递的对象中放置任何视图或其他引用,或者阻止这些对象被垃圾回收,最终可能会耗尽内存(这被称为上下文泄漏 )。

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

 <activity name= ".YourActivity" android:configChanges="orientation|screenSize"/> 

在清单文件?

它在默认情况下不起作用,因为当你改变方向时, onCreate将被再次调用,并重绘你的视图。

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

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

其他方式和另一种方式

首先,您需要确定应用程序中的“状态”实际上是什么。 你没有说你在做什么,但是让我假定对象的ArrayList是用户正在使用的状态。

其次,决定这个状态的生命周期究竟是什么。 这真的与这个活动有关吗? 或者,如果用户说他们的电池电量不足,用户不会失去它,设备将closures,他们以后返回到您的应用程序? 如果前者, onSaveInstanceState()是正确的; 如果是后者,则需要将其保存到onPause()持久性存储中。

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

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

关键function是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.putParcelableArrayList Bundle中了:

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

Activity.onCreate() ,检查是否有一个savedState Bundle ,如果是,则尝试从中检索ArrayList,如果find则使用它,为新的活动创build一个新的适配器和列表视图,用于显示它。

但我注意到,你不能把任意对象放在包中!

首先让你的自定义对象Parcelable
然后你可以把它们放在一个包里。

一切都在这些对象的ArrayList中

您可以在bundle中使用putParcelableArrayList方法来存储自定义“parcelable”对象的ArrayList。

使用Google的Gson将对象写入JSONstring,然后将它们保存为string。 然后,在重build活动/片段时,从保存的JSONstring中构build它们

 import com.google.gson.Gson; public class MyClass { private int a; private String s; private OtherSerializableClass other; private List<String> list; public String toJson() { return new Gson().toJson(this); } public static ChatAPI_MessagesArray fromJson(String json){ return new Gson().fromJson(json, YourClass.class); } // Getters ... // Setters ... }