解决方案:重写onActivityCreated,把这三个Listener都设置为空即可 override fun onActivityCreated(savedInstanceState: Bundle?) { super.onActivityCreated(savedInstanceState) dialog.setOnShowListener(null) dialog.setOnCancelListener(null) dialog.setOnDismissListener(null) } 希望采纳,谢谢! 问题分析:DialogFragment中有一个onActivityCreated方法,Android默认此方法实现是: public void onActivityCreated(@Nullable Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); if (this.mShowsDialog) { View view = this.getView(); if (view != null) { if (view.getParent() != null) { throw new IllegalStateException("DialogFragment can not be attached to a container view"); } this.mDialog.setContentView(view); } Activity activity = this.getActivity(); if (activity != null) { this.mDialog.setOwnerActivity(activity); } this.mDialog.setCancelable(this.mCancelable); this.mDialog.setOnCancelListener(this); this.mDialog.setOnDismissListener(this); if (savedInstanceState != null) { Bundle dialogState = savedInstanceState.getBundle("android:savedDialogState"); if (dialogState != null) { this.mDialog.onRestoreInstanceState(dialogState); } } } } 代码中会默认设置setOnCancelListener和setOnDismissListener this.mDialog.setOnCancelListener(this); this.mDialog.setOnDismissListener(this); 用setOnDismissListener分析一下,setOnCancelListener同理: // Dialog 全局变量 private Message mDismissMessage; // 此方法的实现是在Dialog类中,mDismissMessage是一个全局变量; public void setOnDismissListener(@Nullable OnDismissListener listener) { if (mCancelAndDismissTaken != null) { throw new IllegalStateException( "OnDismissListener is already taken by " + mCancelAndDismissTaken + " and can not be replaced."); } if (listener != null) { // 当listener不为空时,会生成一个Message mDismissMessage = mListenersHandler.obtainMessage(DISMISS, listener); } else { mDismissMessage = null; } } mListenersHandler的定义: private static final class ListenersHandler extends Handler { private final WeakReference<DialogInterface> mDialog; public ListenersHandler(Dialog dialog) { mDialog = new WeakReference<>(dialog); } @Override public void handleMessage(Message msg) { switch (msg.what) { case DISMISS: ((OnDismissListener) msg.obj).onDismiss(mDialog.get()); break; case CANCEL: ((OnCancelListener) msg.obj).onCancel(mDialog.get()); break; case SHOW: ((OnShowListener) msg.obj).onShow(mDialog.get()); break; } } } ListenersHandler主要是当处理Listener时,通过Handler来调用Listener的实现。 调用位置:弹窗关闭的时候 @Override public void dismiss() { if (Looper.myLooper() == mHandler.getLooper()) { dismissDialog(); // 调用关闭弹窗 } else { mHandler.post(mDismissAction); } } void dismissDialog() { if (mDecor == null || !mShowing) { return; } if (mWindow.isDestroyed()) { Log.e(TAG, "Tried to dismissDialog() but the Dialog's window was already destroyed!"); return; } try { mWindowManager.removeViewImmediate(mDecor); } finally { if (mActionMode != null) { mActionMode.finish(); } mDecor = null; mWindow.closeAllPanels(); onStop(); mShowing = false; sendDismissMessage(); // 发送关闭弹窗的消息 } } private void sendDismissMessage() { if (mDismissMessage != null) { // Obtain a new message so this dialog can be re-used Message.obtain(mDismissMessage).sendToTarget(); // 复制了这个消息并且发送到目标的Handler上,这里的Handler就是mListenersHandler(ListenersHandler) } } 因为mDismissMessage是全局变量,obj引用了Listener(DialogFragment),Dialog引用mDismissMessage,相互持有引用,存在引用数,导致内存泄漏。 分析的如有问题请纠正,谢谢。 参考:https://www.cnblogs.com/endur...
解决方案:重写onActivityCreated,把这三个Listener都设置为空即可
希望采纳,谢谢!
问题分析:
DialogFragment中有一个onActivityCreated方法,Android默认此方法实现是:
代码中会默认设置setOnCancelListener和setOnDismissListener
用setOnDismissListener分析一下,setOnCancelListener同理:
mListenersHandler的定义:
ListenersHandler主要是当处理Listener时,通过Handler来调用Listener的实现。
调用位置:
弹窗关闭的时候
因为mDismissMessage是全局变量,obj引用了Listener(DialogFragment),Dialog引用mDismissMessage,相互持有引用,存在引用数,导致内存泄漏。
分析的如有问题请纠正,谢谢。
参考:https://www.cnblogs.com/endur...