java - 更换片段时内存泄漏
问题描述
我刚刚开始使用 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))
这是我的片段替换代码:
public void change(Fragment fragment) {
((FragmentActivity) context).getSupportFragmentManager().beginTransaction()
.replace(R.id.frameLayout, fragment, "fragment")
.setTransitionStyle(FragmentTransaction.TRANSIT_FRAGMENT_FADE)
.addToBackStack(null)
.commit();
}
所以我对 SO 进行了研究,有人说意见必须在onDestroyView
. 然后我尝试了这个onDestroyView
:fragmentView=null;
但没有任何改变。也试过这个:
if (view.getParent() != null) {
((ViewGroup) view.getParent()).removeView(view);
}
但再次没有任何改变。所以我试图让所有视图都为空,如下所示:
@Override
public void onDestroyView() {
super.onDestroyView();
backButton=null;
swipeLayout=null;
imageView=null; ...etc.
}
最终,LeakCanary 上的泄漏警告消失了。但我认为这不是一个解决方案,也没有意义,因为可能有很多意见。那么避免这种泄漏的解决方案是什么?谢谢。
解决方案
所以我试图让所有视图都为空,如下所示
最终,LeakCanary 上的泄漏警告消失了。
View
您已经找到了解决方案 - 在引用(您的backButton
、swipeLayout
、imageView
等)被删除并应该被销毁 ( ) 之后,您一直在持有它们onDestroyView
。由于持有对它们的引用可以防止它们被垃圾收集,这就是内存泄漏。
但我认为这不是一个解决方案,也没有意义,因为可能有很多意见。那么避免这种泄漏的解决方案是什么?
如果您View
手动将 s 存储在成员变量中,那是最好的解决方案。您可以findViewById
每次都使用它来查找它,但我不推荐它,因为重复遍历视图层次结构会导致性能损失。
您可以通过使用Android 开发工具的视图绑定功能来避免这两个问题。有了它,您将只需摆脱一个 Binding 对象。
您还可以使用Butter Knife为您管理视图变量 - 请参阅unbinder.unbind();
该页面上提到的模式。
推荐阅读
- javascript - 点击后HTML将div移动到文本旁边
- azure - 在 Sharepoint 中显示 Dynamics CRM 365 客户
- python - 从列表理解到 numpy.where()
- vue.js - Vue路由器-命名路由错误的缺少参数
- ios - UIImagePickerController isSourceTypeAvailable(type) 始终为真
- javascript - 如何使用 dataTable 过滤日期列
- apache-kafka - 多个分区上的 Spring Kafka 和轮询策略
- java - 如何修复 Object 无法转换为 javafx.scene.Node
- graalvm - Micronaut 数据、GraalVM、AWS 构建失败
- c - M_CACHE、M_DEVBUF、M_TEMP的区别