我想知道orroids垃圾收集器如何处理片段保留的数据(保留实例)。
如果我有类似这样的课程:
class MyFragment extends Fragment {
private DataManager dataManager;
public MyFragment(){
setRetainInstance(true);
}
public void onCreate(){
if (dataManager == null)
dataManager = new DataManager();
dataManager.setView(this);
}
public void onCreateView(){
// display the data of the dataManager
}
public void onStop(){
dataManager.setView(null);
}
}
class DataManager implements DataChangedListener {
private MyFragment view;
private Data data;
public DataManager(){
data.setDataChangedListener(this);
}
public void setView(MyFragment v){
this.view = v;
}
}
class Data {
public void setDataChangedListener(DataChangedListener l){
this.listener = l;
}
}
所以我想做的是,在orientation
上更改片段视图内容将被重新调整。但基础数据(DataManager
和数据)不得重新加载。
DataManager
收听数据对象的更改,并将此更改转发给用户界面Fragment
。 Fragment
已附加&#34; <(1)}时(重新)创建。
到目前为止一切顺利。在我看来,这是一个很好的解决方案,结构合理。基本上是它的某种Model-View-Presenter模式。
但现在我想知道,Android将运行垃圾收集器来收集DataManager
和数据对象。
假设我有一个显示DataManager
的活动。
但是当应用程序的用户导航到另一个活动时,内存会发生什么,显示完全不同的内容。
由于存在从MyFragment
到数据的引用,反之亦然,我猜数据将被永久保留&#34;在记忆中,对吗?
所以我猜垃圾收集器只会在设备进入低内存时才删除它。但我想,这两个对象不会自动成为垃圾收集的前两个数据对象。我猜有某种&#34;内存死锁&#34;。
答案 0 :(得分:0)
关于垃圾收集器:
我可能在这里的一些概念上错了,但据我所知,垃圾收集器从一个已知对象开始并在对象树中“导航”,如果该树上没有任何对象,它将被收集。
因此,例如,它来自活动的统计信息,并且它引用了一些视图,一个适配器和FragmentManger,FragmentManager引用了3个片段,这些片段引用了一些数据对象,依此类推
但是如果Object_A已经引用了Object_B和Object_B到Object_A,但没有其他人引用Object_A或Object_B,那么你可以再吻别那两个。
<强>建议:强>
通常为了简化整个setRetainInstance(true);
交易,我为自己制定了一条规则(记住,这不是强制性的,但确实让生活更容易理解和抽象):如果我想/需要保留数据和将使用setRetainInstance
一个片段没有视图。这意味着,我不会覆盖它的onCreateView
及其上的交易,这是一个简单的add(mFrag, MyFrag.TAG);
,而不是将它放在布局中的任何位置。
这简化了,因为您知道在需要时会重新创建所有视图,并且您始终可以使用getFragmentManager().findFragmentByTag(MyFrag.TAG);
回到GC交易,用这种方法你知道你的数据不会被GC,因为它是由FragmentManager安全保存的。
听起来像个好计划?你觉得怎么样?
修改强>
进一步建议:
不要在DataFragment中保留对任何View,Activity或Context的任何引用。任何长生命对象都不应该保留这些引用,因为它们确实存在整个活动,这是一个巨大的内存泄漏。