3

對於使用setTag方法存儲的ViewHolder中的活動保持句柄是否安全?在ViewHolder中引用活動

,我發現這個問題,聲稱該存儲到活動的引用會導致內存泄漏,但它已被固定在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; 
    } 
} 

與getView方法在我的ArrayAdapter這樣的:

@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; 
} 

(該代碼是一個實際代碼庫的簡化版本只是爲了得到這個觀點。)

我見過的示例代碼都沒有存儲對持有者中的任何內容的引用。我想知道這是巧合還是設計。

回答

4

無論在這種情況下是否安全,最好始終保持上下文引用最小。使用contextMyHolder中處理的所有內容都可以轉換爲在getView()中執行的操作,同時在適配器中保存上下文引用。這是設計的,因爲肯定不需要設計需要多個上下文引用。

+0

當然,對於有些人爲的例子感到抱歉。有時,在填充持有者時,我想引用一些更廣泛的上下文(例如,用於加載圖片的畢加索實例,或者某個內存數據存儲庫以決定填充視圖的準確位置)。在Holder本身上使用填充方法很好,但只有當您可以將引用傳遞給應用程序的其他部分時,它纔會最清晰。 – dsg 2014-09-02 04:58:52

+0

從最簡潔的角度來看,你的意思是從代碼的角度來看,它只是一個代碼塊在一個地方而不是另一個的問題,在這種情況下,記住我們的最小上下文引用的目標,最好是擁有它在適配器中。基本上,如果它需要一個上下文,並且可以在'getView()'中完成,則在'getView()'中執行。 – 2014-09-02 05:16:24