gpt4 book ai didi

android - LeakCanary DialogFragment 泄漏检测

转载 作者:行者123 更新时间:2023-12-02 06:06:21 25 4
gpt4 key购买 nike

每次我尝试显示 DialogFragment 时都会出现内存泄漏。

这就是我的测试对话框(取自 Android 开发者页面)的样子:

public class TestDialog extends DialogFragment {

public static TestDialog newInstance(int title) {
TestDialog frag = new TestDialog();
Bundle args = new Bundle();
args.putInt("title", title);
frag.setArguments(args);
return frag;
}

@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
int title = getArguments().getInt("title");

return new AlertDialog.Builder(getActivity())
.setIcon(R.drawable.ic_action_about)
.setTitle(title)
.setPositiveButton(R.string.ok,
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
//((FragmentAlertDialog)getActivity()).doPositiveClick();
}
}
)
.setNegativeButton(R.string.cancel,
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
//((FragmentAlertDialog)getActivity()).doNegativeClick();
}
}
)
.create();
}
}

我使用以下代码启动它,该代码在按下按钮时执行:

DialogFragment newFragment = TestDialog.newInstance(R.string.company_title);
newFragment.show(getFragmentManager(), "dialog");

这是最好的部分: enter image description here

如何解决此泄漏(或至少隐藏它,因为所有这些通知让 canaryleak 变得非常烦人)?

最佳答案

造成此次泄露的原因是DialogFragment的源代码:

@Override
public void onActivityCreated(Bundle savedInstanceState) {
...
// other codes
...
mDialog.setCancelable(mCancelable);
// hear is the main reason
mDialog.setOnCancelListener(this);
mDialog.setOnDismissListener(this);
...
// other codes
...
}

让我们看看函数 Dialog.SetOnCancelListener(DialogInterface.OnCancelListener) 发生了什么:

/**
* Set a listener to be invoked when the dialog is canceled.
*
* <p>This will only be invoked when the dialog is canceled.
* Cancel events alone will not capture all ways that
* the dialog might be dismissed. If the creator needs
* to know when a dialog is dismissed in general, use
* {@link #setOnDismissListener}.</p>
*
* @param listener The {@link DialogInterface.OnCancelListener} to use.
*/
public void setOnCancelListener(@Nullable OnCancelListener listener) {
if (mCancelAndDismissTaken != null) {
throw new IllegalStateException(
"OnCancelListener is already taken by "
+ mCancelAndDismissTaken + " and can not be replaced.");
}
if (listener != null) {
// here
mCancelMessage = mListenersHandler.obtainMessage(CANCEL, listener);
} else {
mCancelMessage = null;
}
}

并且,这是Handler.obtainMessage(int, Object)的源代码:

    /**
*
* Same as {@link #obtainMessage()}, except that it also sets the what and obj members
* of the returned Message.
*
* @param what Value to assign to the returned Message.what field.
* @param obj Value to assign to the returned Message.obj field.
* @return A Message from the global message pool.
*/
public final Message obtainMessage(int what, Object obj)
{
return Message.obtain(this, what, obj);
}

最后,函数Message.obtain(Handler, int, Object)将被调用:

    /**
* Same as {@link #obtain()}, but sets the values of the <em>target</em>, <em>what</em>, and <em>obj</em>
* members.
* @param h The <em>target</em> value to set.
* @param what The <em>what</em> value to set.
* @param obj The <em>object</em> method to set.
* @return A Message object from the global pool.
*/
public static Message obtain(Handler h, int what, Object obj) {
Message m = obtain();
m.target = h;
m.what = what;
m.obj = obj;

return m;
}

我们可以看到cancelMessage持有DialogFragment的实例,这会导致内存泄漏。我只是想让你知道这一点,除了不要使用 DialogFragment 之外,我没有办法避免它。或者谁有更好的解决方案请告诉我。

关于android - LeakCanary DialogFragment 泄漏检测,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53185154/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com