Android碎片保留数据

5
如何在 Fragment 的 onCreate/Destroy 生命周期中最好地保留数据,例如从旋转中恢复?
在我们的设置中,可能会将从服务器加载到片段自定义列表适配器中的大型列表平滑地展示给用户体验,以避免在旋转时重新加载它们。使用 `fragment retainInstance=true` 时的问题在于适配器有一个对原始活动上下文的引用,因此可能会导致内存泄漏。我们能否只存储数据在 Fragment 中并重新创建适配器?如果可以,那是否是正确的做法?
下一个想法是将数据存储到会话单例对象中,在旋转后检索数据,这样可能会出现一些过时的数据问题,但很容易克服。
我看到的另一种替代方案似乎是最佳解决方案,即将数据保存到 Bundle 中,并在旋转后恢复到新的 Fragment 中。但是,我们有很多需要在整个应用程序中存储的对象,其中一些对象比较复杂,包含列表、多种类型,而且可能难以进行 parcelable 序列化。是否有更好的解决方案,或者我们必须接受它们是 Parcelable 对象的事实?

你考虑将应用程序上下文传递给适配器而不是活动本身吗?如果你没有使用不同主题上下文的复杂操作,我建议你仍然使用应用程序上下文,因为它在应用程序的生命周期内不会改变。 - MH.
3个回答

4
只需防止 Activity 在旋转等情况下重新创建即可。添加:
android:configChanges="keyboardHidden|orientation|screenSize"

在 AndroidManifest.xml 中向您的 Activity 定义添加android:configChanges="orientation|screenSize",然后旋转时无需保存任何内容。
编辑:
如果您不喜欢该解决方案,则只能使用 onSaveInstanceState 机制。如果您有复杂的数据,只需使您的类可序列化并以此方式将它们添加到 Bundle 中即可。

3
由于Android文档和其他地方都强烈反对这种做法,因此我们不认为这是一种可行的选择。 http://developer.android.com/reference/android/app/Activity.html#onRetainNonConfigurationInstance() - Zachary Moshansky
2
那么你别无选择,只能使用 onSaveInstanceState 机制。如果你有复杂的数据,只需将你的类序列化并以此方式添加到 Bundle 中即可。 - Christopher Perry
1
如果您将其作为答案提交,它将被接受为正确答案。最佳解决方案是将数据封装成可传递对象并使用保存实例状态,但由于复杂性,可以通过使用片段的保留实例功能来缓解,并更仔细地管理我们的片段资源以确保不会保留对旧活动/视图的引用(无论如何都应该这样做,以改善性能)。 - Zachary Moshansky

1

0

根据http://developer.android.com/guide/topics/resources/runtime-changes.html,you,只要数据没有与活动、视图等相关联,您完全可以将数据保存在片段中。Bundle 并不适用于大量数据,而序列化速度较慢,因此片段非常适合大量数据。

使用 onSaveInstanceState() 回调系统为您保存的 Bundle 可能无法完全恢复活动状态——它不适用于携带大型对象(例如位图),其中的数据必须进行序列化和反序列化,这可能会消耗大量内存并使配置更改变慢。在这种情况下,当由于配置更改而重新启动您的活动时,您可以保留一个片段来减轻重新初始化活动的负担。该片段可以包含对要保留的有状态对象的引用。


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