当一个片段被replace,并放在后面的堆栈(或删除)是否留在内存中?

行为与“活动”的工作方式相似吗? 例如与活动它像这样工作:

活动A启动活动B ,而B在屏幕上,如果系统需要,系统能够从内存中移除A. 按BACK键后, A将被重新创build到内存中,就好像它从来没有离开过一样。

我已经找了一个明确的解释,发生了什么事情记忆与碎片明智,没有发现任何东西。 它以同样的方式工作吗? 例如:

活动C在其布局中具有片段F. 然后,在某一点F片段Greplace,但是F被保留在其后面的堆栈中。

F留在内存中,直到C被杀死或者可以根据需要被系统删除?

我真正想问的是,如果我在单个活动中有一堆复杂的片段,我是否会面临内存不足的风险?

看看这个: BackStackRecord.Op.fragment

这就是如何将碎片存储在后端堆栈中。 请注意活动参考,既不使用WeakReference也不使用SoftReference

现在这个: FragmentManagerImpl.mBackStack

那就是经理存储后端堆栈的地方。 简单ArrayList ,也没有WR或SR。

最后这个: Activity.mFragments

这是对片段pipe理器的引用。

GC只能收集没有活动引用的对象(不能从任何线程访问)。 这意味着, 直到你的活动被破坏 (所以, FragmentManager引用已经消失), GC将无法收集回栈中的任何碎片

请注意,当Activity被销毁并保持状态时 (如将设备设置为横向模式时),它不会将实际的Fragment对象保留在堆栈中,只有它们的状态–Fragment.FragmentState对象,即后堆栈中的实际碎片每次活动重新创build保留状态时重新创build。

希望这可以帮助。

PS所以,简而言之: 是的,你可以通过添加Fragments来返回堆栈以及通过添加太多的视图来查看层次结构来耗尽内存

UPD考虑你的例子, F将保持在内存中,直到C被杀死。 如果C被杀死,然后以不同的configuration复活,那么F将被毁灭,并在不同的对象转世。 所以, F的内存占用是一直到C失去状态或者退栈被清除。

我很抱歉无法向您提供一些官方的信息来源,但我也很好奇,看看会发生什么,并决定对它进行testing。 而根据我的testing, 是的,你冒着内存不足的风险。

我不得不在OutOfMemoryError的for循环中添加一个令人难以置信的碎片量(超过一百个),但确实发生了。 并检查我的日志,我可以看到onCreate()onCreateView()方法被调用了很多次,但onSaveInstance()onPause()onDestroy根本没有被调用。

作为参考,这是我如何将碎片添加到后台堆栈:

 getSupportFragmentManager().beginTransaction().add(R.id.scene_fragment_container, mSceneFragment).addToBackStack("FOOBAR").commit(); 

我添加的碎片有些简单:一个ImageView ,一个EditText ,一对TextViews ,一个SeekBar和一个ListView

但是除非你在内存中保存了大量的数据,否则不应该是一个问题。

后来我试着在背后join了50个,杀死了这个应用并重新启动了它。 正如我所希望/猜测的,所有的片段都被恢复了(并调用了onSaveInstance()onPause()方法),所以我的生命周期实现不是导致OutOfMemoryError触发的问题。

来自developer.android.com/guide/topics/fundamentals/fragments.html

片段必须始终embedded到活动中,片段的生命周期直接受到宿主活动生命周期的影响。 例如,当活动暂停时,其中的所有片段也是如此,当活动被破坏时,所有片段也是如此。 但是,当一个活动正在运行(处于恢复生命周期状态)时,您可以独立操作每个片段,例如添加或删除它们。 当你执行这样一个片段事务时,你也可以将它添加到由活动pipe理的后端堆栈中 – 活动中的每个后端堆栈条目是发生的片段事务的logging。 后退堆栈允许用户通过按下“后退”button来反转片段事务(向后导航)。

是的,你可以用尽内存在一个单一的活动中创build太多的片段。 只有当包含Activity时,片段才会被销毁。