当我们创建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的引用。这不是在泄漏活动吗?
答案 0 :(得分:1)
虽然这可能无法完全回答您的问题,但以下是一些观察结果:
只要 builder &#34;还活着&#34;垃圾收集器可能不会触及Activity
。
现在,代码中代码片段的代码通常是某些方法的一部分,这些方法将在UI线程上执行(因为涉及UI元素 - AlertDialog
)。
AlertDialog.Builder
实例是在该方法内部创建的,因此一旦方法完成就有资格进行垃圾收集,因为没有任何内容可以保存对它的引用。
另一方面,活动将至少在调用并返回onPause()
之前。
这不会泄露活动吗?
只要该方法在UI线程上运行即可。在其他情况下(例如AsyncTask
),使用WeakReference
可能是个好主意。或者尽可能使用应用程序上下文(例如使用SQLiteOpenHelper
)。
顺便说一下,最近我有一个AlertDialog
,它在方向变化时消失了,而我没有解雇它(AS模拟器,Lollipop)。 Logcat在WindowManager
上显示了一条消息,提到我的Dialog
为&#34;泄露的窗口&#34;,所以我认为现在解雇AlertDialog
对于避免内存泄漏非常重要。
由于我想保持对话框(以及到目前为止的用户输入),我切换到AlertDialog
- 作为 - DialogFragment
解决方案,如文档中的sample。从那以后,警告信息一直没有出现。