我正在从适配器中的演示者请求图像:
// Called when the url of a tab changes.
function checkForValidUrl(tabId, changeInfo, tab) {
if (tab.url.indexOf('calendar') > -1) {
chrome.tabs.insertCSS(null, {code: '.ui-sch input { direction: rtl }'});
chrome.tabs.insertCSS(null, {code: '.ui-sch textarea { direction: rtl }'});
}
};
// Listen for any changes to the URL of any tab.
chrome.tabs.onUpdated.addListener(checkForValidUrl);
我应该在重新使用 @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);
})
);
}
时取消订阅。这很容易。
但是当视图被销毁时如何停止所有订阅?我也应该使演示者引用无效以避免内存泄漏
答案 0 :(得分:20)
我认为最好的办法是:
subscription
SiteAdapter.ViewHolder
引用
unsubscribe
subscription
onBindViewHolder
中的ViewHolder
对象(重新使用CompositeSubscription
时调用此对象)adapter
对象保留在onDetachedFromRecyclerView
Adapter
的{{1}}方法unsubscribe
compositeSubscription
像这样:
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
}
}
}
答案 1 :(得分:2)
答案 2 :(得分:1)
对于其他有相同问题的用户: 仅当将适配器在onPause(活动,片段)或onDetachFromWindow(活动,片段)中设置为null时,才调用适配器中的viewDetachedFromWindow
recyclerview.setAdapter(null)
然后您获得viewDetachedFromWindow(...),可以在其中释放内部状态和订阅。我会在绑定上设置您的订阅,请确保在释放您的每个绑定调用之前释放旧订阅,因为视图可以回收。
另一种可能性是在工厂中增加自定义视图,而不是仅增加布局。然后,您可以在自定义视图onDetachFromWindow()中进行清理。您也可以在不将适配器设置为null的情况下获得onDetachedFromWindow。