Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

should viewholder hold reference to the adapter?

I am reading the sample code from Google, the code is like this:

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

}

You can see every ViewHolder holds a reference (ItemClickListener) to the adapter, since the adapter keeps reference to the ViewHolder already, does anyone know if this kind of implementation would cause memory leak? Please correct me if my understanding is wrong.

like image 838
Yong Liu Avatar asked Nov 15 '15 17:11

Yong Liu


1 Answers

Don't think it would. The ViewHolder cannot exist without the Adapter, and will be garbage collected well before the Adapter is, since the ViewHolders are constantly being recycled by the Adapter as the RecyclerView is scrolled. The interface pattern being used is just a common way of notifying the Adapter that a certain ViewHolder has been clicked. I suppose you could leak memory if you do the opposite by holding a reference to a specific ViewHolder in a member variable inside the Adapter since that could prevent the ViewHolder from being GC'd. Nevertheless, the above code seems pretty standard.

like image 70
crymson Avatar answered Oct 13 '22 17:10

crymson