当我们创建AlertDialog.Builder时,我们传递将显示Dialog的Activity的上下文 .
AlertDialog.Builder builder = new Builder(getActivity()); <<< Activity Context passed as argument
mAlertDialog = builder.create();
mAlertDialog.show();
现在要避免ActivityLeakedException,我们必须在销毁Activity时解除()对话框 . (让我们说屏幕上的roatation) . 这个dismiss()将在Dialog引用上调用,而不是在构建器上调用 . 即使我们在Dialog上调用了dismiss(),构建器也无法知道Activity是如何被销毁的,它应该释放上下文,因此构建器持有对Activity Context的引用 . 这不是泄漏活动吗?
1 回答
虽然这可能无法完全回答您的问题,但以下是一些观察:
只要构建器"is alive"垃圾收集器可能无法触及
Activity
.现在,代码中的代码片段通常是在UI线程上执行的某些方法的一部分(因为涉及到UI元素 -
AlertDialog
) .AlertDialog.Builder
实例是在该方法内创建的,因此一旦方法完成就有资格进行垃圾收集,因为没有任何东西可以保存对它的引用 .另一方面,活动将至少在
onPause()
被调用并返回之前 .只要该方法在UI线程上运行即可 . 在其他情况下(例如
AsyncTask
),使用WeakReference
可能是个好主意 . 或者尽可能使用应用程序上下文(例如使用SQLiteOpenHelper
) .顺便说一下,最近我有一个
AlertDialog
,它在方向变化时消失了而没有我解雇它(AS模拟器,Lollipop) . Logcat在WindowManager
上显示了一条消息,提到我的Dialog
为"leaked window",所以我认为现在解雇AlertDialog
对于避免内存泄漏非常重要 .由于我想保持对话框(以及到目前为止的用户输入),我切换到
AlertDialog
-as-DialogFragment
解决方案,如文档中的sample . 此后,警告消息尚未显示 .