点击项目时我有一个Feed转到详细信息,在它分离FeedFragment并推送DetailsFragment。回去时我们正在检查适配器是否为空。
if (adapter == null) {
adapter = createAdapter();
}
if (recyclerView.getAdapter() == null) {
recyclerView.setAdapter(adapter);
}
问题在于每次重新使用适配器时都会返回详细信息并返回ViewHolders的数量加倍。它可以继续,直到它将冻结应用程序和OOM发生。
问题是为什么会发生这种情况?难道适配器不能与recyclerView分离,所有项目都应该回收吗?
P.S。在返回时创建新适配器时不会发生此问题。
答案 0 :(得分:4)
我认为您正在泄漏RecyclerView
s(及其引用的所有内容,包括视图池)
RecyclerView
在适配器(Adapter.registerAdapterDataObserver
)上注册自己,但只有在设置了新适配器时它才会注销(它从旧的注册表中取消注册并在新的注册表上注册)。因此,适配器保留先前RecyclerView
实例的引用,防止它们被垃圾回收。
我能想到的解决方案是:
从RecyclerView
中的适配器手动取消注册Fragment.onDestroyView()
。我知道这样做的唯一方法是致电RecyclerView.setAdapter(null)
每次都使用新的适配器。它应该是相对轻量级的对象,至少与RecyclerView
本身相比。
另外,如果您希望每次都避免重新创建一组ViewHolders
,则可以在RecyclerView
个实例之间共享RecycledViewPool。 (我刚刚发现了这个,我不确定它应该如何使用)
答案 1 :(得分:0)
我建议的解决方案就是这样,你应该在适配器类中有一个明确的适配器函数,
public void clearAdaptor() {
if (<T>dataList != null && <T>dataList.size() > 0) {
<T>dataList.clear();
notifyDataSetChanged();
}
}
最初设置适配器后需要调用此函数。
adaptorObj = new Adaptor(/**Your implementation**/);
mRecyclerView.setAdapter(adaptorObj);
adaptorObj.clearAdaptor();
getYourData();
获取数据后,请致电
adaptorObj.notifyDataSetChanged();
PS:如果数据是动态的,这是一个可行的解决方案,但如果数据是静态的,也可以修改。