考虑到这种情况:如果我创建了一个活动,并且它移至后台并且此活动包含设置为Fragment
的{{1}},那么Android操作系统可能在某些时候仍然决定关闭活动的托管过程,以释放内存。
然后通过setRetainInstance(true)
保存Activity
的状态 - 据我所知 - 相关的onSaveInstanceState(Bundle)
已写入文件系统,以便在关闭过程中继续存在。 (因此捆绑中对象的要求为Bundle
)。稍后,可以通过Serializable
在新流程中检索应用程序状态。
相反,我的onRestoreInstanceState(Bundle)
包含的变量不一定是Fragment
。因此,我想,Serializable
无法像Fragment
那样存储在磁盘上。那么当进程被杀死时,我的片段会发生什么?
我想知道这阅读开发人员指南(http://developer.android.com/guide/components/processes-and-threads.html):
包含当前对用户不可见的活动的流程 (已调用活动的onStop()方法)。这些过程有 没有直接影响用户体验,系统可以杀死他们 在任何时候回收前景,可见或服务的内存 处理。通常有很多后台进程在运行,所以它们 保存在LRU(最近最少使用)列表中以确保 具有用户最近看到的活动的过程是 最后被杀。 如果某个活动实现了其生命周期方法 正确,并保存其当前状态,杀死其进程不会 对用户体验有明显的影响,因为当用户 导航回活动,活动恢复所有活动 可见状态。
我理解上面的 kill ,以便关闭VM实例并将进程的状态写入文件系统(这里是Bundle
进行播放)。稍后读取包以恢复该过程。由于片段的保留不涉及生命周期方法,因为我不知道如何保留例如一个指向网络连接的指针(你当然应该永远不会在片段中有这样的指针),我想知道如果在此期间关闭进程,片段是否仍然被恢复。我的结论是,他们肯定需要重新创建,因此生命周期方法应尽可能优先于Bundle
。
这个假设是否有意义?
答案 0 :(得分:18)
听起来像你在这里混淆了两个概念。
setRetainInstance()
请求Fragment
,那么这意味着它将完全保留在内存中,而不是仅为重新创建以进行配置更改。类似的机制可用于Activity
个对象,但是它们需要明确定义将要保存的Object
。这可以通过Activity.onRetainNonConfigurationInstance()
,而不是通过onSaveInstanceStae()
。Activity
/ Fragment
被破坏(这是独立发生的)它的托管Process
,顺便说一句。这适用于Activity.onSaveInstanceState()
和Fragment.onSaveInstanceState()
。关于你的问题。
Activity
也是如此。它可以包含不可序列化的对象,可以在配置更改中保存,如上所述。希望我能为澄清这一点做出贡献。
第一次评论后修改。
关于评论:
onRetainNonConfigurationInstance
已被弃用":是的。我之所以提到它是出于演示目的,因为你的问题中有一个特定的措辞。此外,由于Android 2设备目前拥有46%的市场份额(谷歌官方数据),这种方法肯定会在非常长时间内保持不变,不论是否弃用。setRetainInstanceState
时,仅完成此操作。 (但请注意,这与 Instance 相关,换言之,与完整对象有关。)关于你的编辑:
Fragment
Bundle
将存储并恢复到{{1如果您为此目的使用Bundle
,那么无论 setRetainInstanceState
Fragment.onSaveInstanceState()
属性将不保存。这不应该是我不知道的错误或功能,但它是事实。但这只是一个侧面评论; UI元素将保存大部分相关状态。visibility
并实际实现保存其状态的对象状态将保存在Bundle
中,意味着如果您希望Bundle
保存某些州信息,您必须自己提供此类信息。此外,再次:否,这不仅与杀死进程有关,还与删除不可见的Fragment
和Activity
个对象有关;就像显示的最后一个活动一样 - Fragment
可能会保持活力。Process
将被读取将其传递给Activity和/或Fragment对象的重构,在此过程中自动完成 nothing (除了保存状态的库对象也恢复其状态),但 Android 不& #34;履历" "流程"来自这些Bundle
s。Bundle
请求的,但我们主要谈论的是在此处Fragment
创建setRetainInstance
个对象,其中 涉及Google记录的生命周期方法。Fragment
的要求),因为当发生这种情况时,所有内容都会保留在内存中。此外,即使您的Bundle
被删除(因为它变得不可见)并且您的进程仍在那里(因为它显示了下一个Activity),您也可以(并且应该)保留对重新创建的对象的引用您的setRetainInstance
对象中的网络连接,例如网络连接,只要您的进程存在(或多或少),就会存在。当您的整个应用被Android杀死时,只有 才会丢失所有内容,但我们正在讨论的序列化经常发生 你的结论:
我得出结论,他们肯定需要重新创建,因此生命周期方法应尽可能优于setRetainInstance(true)。这个假设有意义吗?
不幸的是,因为你混合了完全独立的概念。
我将最后一次尝试:
Fragment
对象中的整个应用中保留网络连接引用,因为如果您是从头开始创建它,那将是一种糟糕的用户体验整个应用程序的基础。Application
对象才会死亡。Application
和Application
个对象将定期从您的应用中删除。Activity
重新创建Fragment
和Activity
个对象。如果你有重新创建内部状态的昂贵计算,那么在Bundle中保存一些东西是有意义的。您可以在没有Fragment
机制的情况下生活,因为Android会始终保存Bundle
,因此如果您不做任何事情,那么您将在没有保存状态的情况下启动。Bundle
生命周期方法得到了解决,并且由您的实现来有效地使用保存的数据。对于Intent
s,如果你设置它,Activity
Fragment`将在内存中的配置更改中存活。