DialogFragment内存泄露问题能不能一次性改好,android开发者周报

本文探讨了DialogFragment内存泄漏的问题,指出真正的原因是Dialog而非DialogFragment。通过分析DialogFragment源码,作者提出创建NoLeakDialog,避免在监听器中持有外部引用。然而,测试发现点击空白区域关闭弹窗后,再次返回仍会显示。通过注释发现,DialogFragment的onDismiss方法在某些情况下会重新显示对话框。为解决此问题,作者在NoLeakDialog中添加回调,确保正确关闭DialogFragment。
摘要由CSDN通过智能技术生成

其实一路过来无论是网上的资料还是LeakCanary都是告诉我们是说是DialogFragment发生了内存泄漏,但是罪魁祸首真的是DialogFragment吗?罪魁祸首是DialogFragment内部的Dialog啊,我们为什么一直揪着DialogFragment不放呢?为什么一直想着给DialogFragment治病呢?能不能给DialogFragment它内部的Dialog治治啊?

通过查看DialogFragment的源码我们发现它内部的mDialog是通过onCreateDialog方法生成的,而且这个方法是开放的。那么我们能不能通过重写这个方法,返回一个不会对DialogFragment持有强引用的Dialog不就完事了吗?

那么我们就重写一个Dialog名为NoLeakDialog:

public class NoLeakDialog extends Dialog {

public NoLeakDialog(@NonNull Context context, int themeResId) {

super(context, themeResId);

}

@Override

public void setOnCancelListener(@Nullable OnCancelListener listener) {

// 空实现,不持有外部的引用

}

@Override

public void setOnShowListener(@Nullable OnShowListener listener) {

// 空实现,不持有外部的引用

}

@Override

public void setOnDismiss

DialogFragment内存泄漏通常是由于它与Activity的生命周期不一致而导致的。比如,在DialogFragment中使用了Activity的Context,而DialogFragment在Activity销毁之前没有被销毁,那么Activity所持有的DialogFragment引用就会一直存在,从而导致内存泄漏。 解决方法有以下几种: 1. 尽量避免在DialogFragment中持有Activity的引用,使用Application Context或者其他非Activity的Context。 2. 在DialogFragment中使用静态内部类或者弱引用来持有Activity的引用,从而避免内存泄漏。 3. 在DialogFragment的onDetach()方法中将Activity的引用置为null,从而解除对Activity的引用,让GC可以回收DialogFragment。 以下是一个使用静态内部类来避免DialogFragment内存泄漏的例子: ``` public class MyDialogFragment extends DialogFragment { private static WeakReference<Activity> sActivityRef; public static void show(Activity activity) { sActivityRef = new WeakReference<>(activity); MyDialogFragment dialogFragment = new MyDialogFragment(); dialogFragment.show(activity.getFragmentManager(), "MyDialogFragment"); } @Override public void onAttach(Context context) { super.onAttach(context); if (sActivityRef != null) { Activity activity = sActivityRef.get(); if (activity != null) { // do something with activity } } } @Override public void onDetach() { super.onDetach(); sActivityRef = null; } } ``` 使用时,可以调用MyDialogFragment.show()方法来显示DialogFragment,这样就可以避免在DialogFragment中持有Activity的引用,避免内存泄漏
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值