我刚刚开始使用 LeakCanary,当我更换 Fragment 时,每次泄漏都会增加。这是 LeakCanary 报告:
android.widget.LinearLayout instance
Leaking: YES (ObjectWatcher was watching this because com.home.app1.PostFragment received Fragment#onDestroyView() callback
(references to its views should be cleared to prevent leaks))
这是我的 fragment 替换代码:
public void change(Fragment fragment) {
((FragmentActivity) context).getSupportFragmentManager().beginTransaction()
.replace(R.id.frameLayout, fragment, "fragment")
.setTransitionStyle(FragmentTransaction.TRANSIT_FRAGMENT_FADE)
.addToBackStack(null)
.commit();
}
所以我研究了 SO,有人说 View 必须在
onDestroyView
中清除。 .然后我在 onDestroyView
中尝试了这个: fragmentView=null;
但什么都没有改变。也试过这个:if (view.getParent() != null) {
((ViewGroup) view.getParent()).removeView(view);
}
但再次没有任何改变。所以我试图让所有 View 都为空,如下所示:
@Override
public void onDestroyView() {
super.onDestroyView();
backButton=null;
swipeLayout=null;
imageView=null; ...etc.
}
最终,LeakCanary 上的泄漏警告消失了。但我认为这不是一个解决方案,也没有意义,因为可能有很多意见。那么避免这种泄漏的解决方案是什么?谢谢。
最佳答案
So I tried to make all views null like below
Eventually leaking warnings on LeakCanary disappeared.
你已经找到了解决方案——你一直在坚持
View
引用(您的 backButton
、 swipeLayout
、 imageView
等)被删除并应该被销毁( onDestroyView
)。由于持有对它们的引用可以防止它们被垃圾收集,这就是内存泄漏。But I think this is not a solution and does not make sense because there may be many views. So what's the solution to avoid this leaks?
如果您要存储
View
s 在成员变量中手动,这是最好的解决方案。您可以使用 findViewById
每次都找到它,但我不推荐它,因为重复遍历 View 层次结构会导致性能损失。您可以使用 View Binding 来避免这两个问题。 Android 开发工具的特性。有了它,您将只需摆脱一个 Binding 对象。
您也可以使用 Butter Knife为您管理 View 变量 - 请参阅
unbinder.unbind();
该页面上提到的模式。
关于java - 更换 fragment 时内存泄漏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61743869/