Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
185 views
in Technique[技术] by (71.8m points)

android - What is lifecycle for RecyclerView adapter?

I'm requesting images from presenter in adapter:

  @Override
  public void onBindViewHolder(SiteAdapter.ViewHolder holder, int position)
  {
    Site site = sites.get(position);
    holder.siteName.setText(site.getName());
    requestHolderLogo(holder, site.getLinks().getLogoUrl());
  }

  private void requestHolderLogo(final ViewHolder holder, final String logoUrl)
  {
    compositeSubscription.add(
      presenter.bitmap(logoUrl)
        .subscribe(
          bitmap -> {
            holder.siteLogo.setImageBitmap(bitmap);
            holder.siteLogo.setVisibility(View.VISIBLE);
          },
          error -> {
            holder.siteName.setVisibility(View.VISIBLE);
          })
    );
  }

I should unsubscribe when ViewHolder is re-used. It is easy.

But how stop all subscription when view is destroyed? I should also probably nullify presenter reference to avoid memory leak

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

I think the best way to do that would be to:

  1. Keep a subscription reference in the SiteAdapter.ViewHolder
  2. unsubscribe the subscription object in onBindViewHolder (it's called when the ViewHolder is reused)
  3. Keep the CompositeSubscription object in your adapter
  4. Use the onDetachedFromRecyclerView method of your Adapter to unsubscribe the compositeSubscription

Like so:

public class SiteAdapter extends RecyclerView.Adapter<SiteAdapter.ViewHolder> {

    private CompositeSubscription compositeSubscription = new CompositeSubscription();

    // other needed SiteAdapter methods

    @Override
    public void onBindViewHolder(SiteAdapter.ViewHolder holder, int position) {
        if (holder.subscription != null && !holder.subscription.isUnsubscribed()) {
            compositeSubscription.remove(holder.subscription);
            // this will unsubscribe the subscription as well
        }
        Site site = sites.get(position);
        holder.siteName.setText(site.getName());
        requestHolderLogo(holder, site.getLinks().getLogoUrl());
    }

    private void requestHolderLogo(final SiteAdapter.ViewHolder holder, final String logoUrl) {
        holder.subscription = presenter.bitmap(logoUrl)
                .subscribe(
                        bitmap -> {
                            holder.siteLogo.setImageBitmap(bitmap);
                            holder.siteLogo.setVisibility(View.VISIBLE);
                        },
                        error -> {
                            holder.siteName.setVisibility(View.VISIBLE);
                        });
        compositeSubscription.add(holder.subscription);
    }

    @Override
    public void onDetachedFromRecyclerView(RecyclerView recyclerView) {
        compositeSubscription.unsubscribe();
    }

    public static class ViewHolder extends RecyclerView.ViewHolder {

        public Subscription subscription;

        // some holder-related stuff

        public ViewHolder(View itemView) {
            super(itemView);
            // init holder
        }
    }
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...