2

我想知道 androids 垃圾收集器如何处理片段(保留实例)保存的数据。

如果我有这样的班级层次结构:

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更改,并将此更改转发到 UI Fragment,. Fragment被“附加”到DataManager它(重新)创建的时间。

到目前为止,一切都很好。在我看来,这是一个很好的解决方案并且结构良好。基本上它是某种模型-视图-演示者模式。

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

假设我有一个显示MyFragment.

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

由于有DataManager对 Data 的引用,反之亦然,我猜数据将“永远”保存在内存中,对吧?所以我猜垃圾收集器只会在设备内存不足时删除它。但我想,这两个对象不会自动成为垃圾收集的前两个数据对象。我想有某种“内存死锁”。

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

4

1 回答 1

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 中保留对任何视图、活动或上下文的任何引用。任何长期存在的对象都不应该保留这些引用,因为它们确实保存了整个活动,这是一个巨大的内存泄漏。

于 2013-03-05T09:39:12.837 回答