What's the way to go if I want my ViewHolders in an RecyclerView to clean up internal state (in this case unregister from an EventBus and clean up Rx-Subscriptions)?
I thought that the methods onViewDetachedFromWindow
or onViewRecycled
in the adapter is the callback where I can cleanup resources (as described in the API), but this method is never called when I change from the Activity
with the RecyclerView
to another Activity
.
Only onViewAttachedToWindow
is called when the activity is entered and i can see my items.
My adapter looks like this:
public class Adapter extends RecyclerView.Adapter<MyViewHolder>
{
@Override
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
return factory.getViewholder(parent, viewType, this);
}
@Override
public void onBindViewHolder(MyViewHolder holder, int position) {
MyItem item = items.get(position);
holder.bind(item);
}
@Override
public void onViewDetachedFromWindow(MyViewHolder holder)
{
holder.viewDetached();
super.onViewDetachedFromWindow(holder);
}
@Override
public void onViewAttachedToWindow(MyViewHolder holder)
{
super.onViewAttachedToWindow(holder);
holder.viewAttached();
}
@Override
public void onViewRecycled(MyViewHolder holder)
{
super.onViewRecycled(holder);
holder.viewRecycled();
}
@Override
public int getItemCount() {
return items.size();
}
@Override
public int getItemViewType(int position)
{
return items.get(position).getType(this.factory);
}
}
The Activity
holding the RecyclerView
:
public class MyActivity extends AppCompatActivity
{
protected void setupView()
{
//called in onCreate
recyclerView = (RecyclerView) findViewById(R.id.recyclerView);
recyclerView.setLayoutManager(new GridLayoutManager(this, 3));
this.adapter = new Adapter(new ItemViewHolderFactory());
}
@Override
public void setItems(List<MyItem> items)
{
//items are loaded async
this.adapter.setItems(items);
this.recyclerView.setAdapter(this.adapter);
this.recyclerView.scheduleLayoutAnimation();
}
}
The ViewHolder looks like this
public class MyViewHolder extends RecyclerView.ViewHolder
{
public void bind(MyItem item)
{
//set initial data
}
public void viewAttached()
{
registerToEventBus();
loadDataAsync(); // here an rx operation is scheduled and a subscription is hold
}
public void viewDetached()
{
unregisterFromEventBus();
cancelAsyncOperationAndCleanSubscription();
}
}
Thanks for any advices.
EDIT
I tried to override onDetachedFromRecyclerView
in the adapter, but this method is also not called.