Android非静态内部类内存问题

时间:2015-07-16 11:15:31

标签: android memory-leaks inner-classes non-static

我在我的一个适配器中编写了以下类。该类从构造函数中的活动获取视图:

    private class ContactViewHolder {
       public TextView tvPrimary;
       public TextView tvSecondary;
       public ImageView imageViewCheck;


       public ContactViewHolder(View v) {
           this.tvPrimary = (TextView) v.findViewById(R.id.tv_primary);
           this.imageViewCheck = (ImageView) v.findViewById(R.id.iv_check);
           v.findViewById(R.id.iv_mm_user);
           this.tvSecondary = (TextView) v.findViewById(R.id.tv_secondary);
       }
   }

这会导致内存泄漏问题吗? 它似乎可能会导致内存泄漏,如this link中所述,关于一个稍微不同的问题。

所以,总而言之,我想知道:

  1. 这会导致内存泄漏问题吗?
  2. 如果是,为什么?

2 个答案:

答案 0 :(得分:0)

如果您定义这样的实例:

static ContactViewHolder  holder = new ContactViewHolder(view);

会导致内存泄漏。

如果您定义了非静态实例,则它没有内存泄漏。

泄漏的原因如下:

非静态内部类将保存outter类实例的引用,因此静态holder将保存适配器的引用。 众所周知,GC无法收集静态实例,它是gc root,因此在进程终止之前无法收集适配器。

答案 1 :(得分:0)

当您不知道/控制内部类对象的生命周期时,会发生内存泄漏。因为没有被GC收集,所以保持他的对象不会被收集等等,这会导致内存泄漏。基本上如果你的持有者只用你写的最简单的方式处理ui,那么他就没有办法“超过”包含他的适配器然后它不会导致内存泄漏。

如果由于某种原因你在Holder中实现了onClick监听器,例如打开一个AsyncTask,那么你就不会控制对象的生命周期,因为它会打开一个新的Thread并且可能在适配器不再运行时进行一些操作在UI上,这将导致内存泄漏。

结论: 要非常了解对象的生命周期以及拥有对象的人员。