泄漏金丝雀,Recyclerview泄漏的mAdapter [英] Leak canary, Recyclerview leaking mAdapter

查看:351
本文介绍了泄漏金丝雀,Recyclerview泄漏的mAdapter的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我认为是时候该学会了如何使用Leak Canary来检测我的应用程序中的泄漏了,并且像往常一样,我尝试在我的项目中实现它以真正了解如何使用该工具.实施起来很容易,困难的部分是阅读该工具给我带来了什么. 我有一个scrollview,它在上下滚动时似乎在内存管理器中累积内存(即使它不会加载任何新数据),所以我认为这是跟踪泄漏的一个不错的候选对象,这是结果:

看起来v7.widget.RecyclerView正在泄漏适配器,而不是我的应用程序.但这不对...对吗?

这是适配器的代码以及使用它的类: https://gist.github.com/feresr/a53c7b68145d6414c40ec70b3b842f1e

我开始悬赏这个问题,因为两年后在另一个完全不同的应用程序上又浮出水面了

解决方案

如果适配器的寿命比RecyclerView的寿命长,则必须清除onDestroyView中的适配器引用:

@Override
public void onDestroyView() {
    recyclerView.setAdapter(null);
    super.onDestroyView();
}

否则,适配器将保留对RecyclerView的引用,该引用本应已耗尽内存.

如果屏幕包含过渡动画,则实际上您必须进一步执行此步骤,并且仅在视图已分离时清除适配器:

@Override
public void onDestroyView() {
    recyclerView.addOnAttachStateChangeListener(new View.OnAttachStateChangeListener() {
        @Override
        public void onViewAttachedToWindow(View v) {
            // no-op
        }

        @Override
        public void onViewDetachedFromWindow(View v) {
            recyclerView.setAdapter(null);
        }
    });
    super.onDestroyView();
}

I decided it was high time I learned how to use Leak Canary to detect Leaks within my apps, and as I always do, I tried to implement it in my project to really understand how to use the tool. Implementing it was easy enough, the difficult part was reading what the tool is throwing back at me. I have a scrollview that seems to accumulate memory in the memory manager as I scroll up and down (even though It doesnt load any new data) so I thought that was a good candidate object to track leaks on, this is the result:

It looks like v7.widget.RecyclerView is leaking the adapter, and not my application. But that can't be right.... right?

Here's the code for the adapter and the class making use of it: https://gist.github.com/feresr/a53c7b68145d6414c40ec70b3b842f1e

I started a bounty for this question because it resurfaced after two years on a completely different application

解决方案

If the adapter lives any longer than the RecyclerView does, you've got to clear the adapter reference in onDestroyView:

@Override
public void onDestroyView() {
    recyclerView.setAdapter(null);
    super.onDestroyView();
}

Otherwise the adapter is going to hold a reference to the RecyclerView which should have already gone out of memory.

If the screen is involved in transition animations, you actually have to take this one step further and only clear the adapter when the view has become detached:

@Override
public void onDestroyView() {
    recyclerView.addOnAttachStateChangeListener(new View.OnAttachStateChangeListener() {
        @Override
        public void onViewAttachedToWindow(View v) {
            // no-op
        }

        @Override
        public void onViewDetachedFromWindow(View v) {
            recyclerView.setAdapter(null);
        }
    });
    super.onDestroyView();
}

这篇关于泄漏金丝雀,Recyclerview泄漏的mAdapter的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆