引用ViewHolder中的Activity

时间:2014-09-02 03:43:39

标签: android performance android-arrayadapter android-adapter android-viewholder

在使用setTag方法存储的ViewHolder中保留Activity的句柄是否安全?

我发现此问题声称存储对Activity的引用可能会导致内存泄漏,但已在Android 4.0中修复:https://code.google.com/p/android/issues/detail?id=18273

具体来说,我想知道看起来像这样的ViewHolder是否安全:

class MyHolder {
  private Context context; // <<-- is this safe to keep here??
  private TextView textView;

  public MyHolder(Context context) {
    this.context = context;
  }

  public void populate(Doc doc) {
    textView.setText(context.getString(doc.getTextId()));
  }

  public View inflate(ViewGroup parent) {
    View view = LayoutInflater.from(parent.getContext()).inflate(
        R.layout.doc_item, parent, false);

    textView = (TextView)view.findViewById(R.id.doc_item_text);

    return view;
  }
}

在我的ArrayAdapter中使用getView方法,如下所示:

@Override
public View getView(int position, View row, ViewGroup parent) {

    Doc doc = getItem(position);

    MyHolder holder;
    if (row != null) {
        holder = (MyHolder) row.getTag();
    } else {
        holder = new MyHolder(getContext());
        row = holder.inflate(parent);

        row.setTag(holder);
    }

    holder.populate(doc);

    return row;
}

(代码是实际代码库的简化版本,只是为了明白这一点。)

我见过的示例代码中没有一个存储引用除了持有者中的视图之外的任何内容。我想知道这是巧合还是设计。

1 个答案:

答案 0 :(得分:4)

无论在这种情况下它是否安全,最好将Context引用保持在最低限度。您在context中使用MyHolder执行的所有操作都可以转换为getView()中执行的操作,并在适配器中保留上下文参考。这将是设计,因为当然不需要您的设计需要多个Context引用。