Android:Fragment保留实例内存管理

时间:2013-03-05 08:59:33

标签: android garbage-collection fragment

我想知道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收听数据对象的更改,并将此更改转发给用户界面FragmentFragment已附加&#34; <(1)}时(重新)创建。

到目前为止一切顺利。在我看来,这是一个很好的解决方案,结构合理。基本上是它的某种Model-View-Presenter模式。

但现在我想知道,Android将运行垃圾收集器来收集DataManager和数据对象。

假设我有一个显示DataManager的活动。

但是当应用程序的用户导航到另一个活动时,内存会发生什么,显示完全不同的内容。

由于存在从MyFragment到数据的引用,反之亦然,我猜数据将被永久保留&#34;在记忆中,对吗? 所以我猜垃圾收集器只会在设备进入低内存时才删除它。但我想,这两个对象不会自动成为垃圾收集的前两个数据对象。我猜有某种&#34;内存死锁&#34;。

你怎么看?有什么建议吗?

1 个答案:

答案 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的任何引用。任何长生命对象都不应该保留这些引用,因为它们确实存在整个活动,这是一个巨大的内存泄漏。