2015-11-15 13 views
8

Tôi đọc mã mẫu từ Google, mã này là như thế này:nên tham chiếu giữ người xem với bộ điều hợp không?

public class AttractionListFragment extends Fragment { 
... 

private class AttractionAdapter extends RecyclerView.Adapter<ViewHolder> 
     implements ItemClickListener { 

    public List<Attraction> mAttractionList; 
    private Context mContext; 

    public AttractionAdapter(Context context, List<Attraction> attractions) { 
     super(); 
     mContext = context; 
     mAttractionList = attractions; 
    } 

    @Override 
    public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { 
     Log.d("TEST", "onCreateViewHolder"); 
     LayoutInflater inflater = LayoutInflater.from(mContext); 
     View view = inflater.inflate(R.layout.list_row, parent, false); 
     return new ViewHolder(view, this); 
    } 

    @Override 
    public void onBindViewHolder(ViewHolder holder, int position) { 
     Attraction attraction = mAttractionList.get(position); 

     holder.mTitleTextView.setText(attraction.name); 
     holder.mDescriptionTextView.setText(attraction.description); 
     Glide.with(mContext) 
       .load(attraction.imageUrl) 
       .diskCacheStrategy(DiskCacheStrategy.SOURCE) 
       .placeholder(R.drawable.empty_photo) 
       .override(mImageSize, mImageSize) 
       .into(holder.mImageView); 

     String distance = 
       Utils.formatDistanceBetween(mLatestLocation, attraction.location); 
     if (TextUtils.isEmpty(distance)) { 
      holder.mOverlayTextView.setVisibility(View.GONE); 
     } else { 
      holder.mOverlayTextView.setVisibility(View.VISIBLE); 
      holder.mOverlayTextView.setText(distance); 
     } 
    } 

    @Override 
    public long getItemId(int position) { 
     return position; 
    } 

    @Override 
    public int getItemCount() { 
     return mAttractionList == null ? 0 : mAttractionList.size(); 
    } 

    @Override 
    public void onItemClick(View view, int position) { 
     View heroView = view.findViewById(android.R.id.icon); 
     DetailActivity.launch(
       getActivity(), mAdapter.mAttractionList.get(position).name, heroView); 
    } 
} 

private static class ViewHolder extends RecyclerView.ViewHolder 
     implements View.OnClickListener { 

    TextView mTitleTextView; 
    TextView mDescriptionTextView; 
    TextView mOverlayTextView; 
    ImageView mImageView; 
    ItemClickListener mItemClickListener; 

    public ViewHolder(View view, ItemClickListener itemClickListener) { 
     super(view); 
     mTitleTextView = (TextView) view.findViewById(android.R.id.text1); 
     mDescriptionTextView = (TextView) view.findViewById(android.R.id.text2); 
     mOverlayTextView = (TextView) view.findViewById(R.id.overlaytext); 
     mImageView = (ImageView) view.findViewById(android.R.id.icon); 
     mItemClickListener = itemClickListener; 
     view.setOnClickListener(this); 
    } 

    @Override 
    public void onClick(View v) { 
     mItemClickListener.onItemClick(v, getAdapterPosition()); 
    } 
} 

interface ItemClickListener { 
    void onItemClick(View view, int position); 
} 

}

Bạn có thể thấy tất cả các ViewHolder giữ một tham chiếu (ItemClickListener) để adapter, kể từ adapter giữ tham chiếu đến ViewHolder đã có, không ai biết nếu loại thực hiện sẽ gây ra rò rỉ bộ nhớ? Hãy sửa tôi nếu hiểu biết của tôi sai.

Trả lời

0

Đừng nghĩ vậy. ViewHolder không thể tồn tại mà không có Adapter, và sẽ được thu thập rác tốt trước khi Adapter là, vì ViewHolders liên tục được tái chế bởi Adapter khi RecyclerView được cuộn. Mẫu giao diện đang được sử dụng chỉ là một cách phổ biến để thông báo cho Bộ điều hợp rằng một ViewHolder nhất định đã được nhấp. Tôi cho rằng bạn có thể bị rò rỉ bộ nhớ nếu bạn làm điều ngược lại bằng cách giữ một tham chiếu đến một ViewHolder cụ thể trong một biến thành viên bên trong Adapter vì điều đó có thể ngăn ViewHolder khỏi bị GC. Tuy nhiên, đoạn mã trên có vẻ khá chuẩn.

Các vấn đề liên quan