我正在开发一个应用程序,其中90%的活动都是从一个共同的活动继承而且所有这些活动都会泄漏,这意味着如果我从A->B
开始,然后B->A
({{1} }被调用),finish()
的{{1}}被调用,但它仍然泄漏(用MAT检查)。
泄露的活动相当大(10MB~)所以经过几次来回移动应用程序崩溃了。
我已经检查了堆转储,并按照GC根的路径进行了泄漏活动,它们看起来像这样:
所以我猜这是普通超类泄漏的东西。我已经检查过,当活动被破坏并且没有使用B
时,所有的BroadcastReceivers和监听器都没有注册,也没有匿名的内部类可能导致泄漏(至少在我看来)。 / p>
泄漏的原因是什么?任何帮助都会非常感激。
修改
我发现有两段代码在注释掉活动时不再泄漏:
onDestroy()
的一些代码行。Handler
致电ProgressDialog
。在第一种情况下,对话框的postDelayed
函数在销毁之前被调用,所以我不知道为什么这可能是问题。在第二种情况下,为Runnable
中的dismiss()
调用removeCallbacks,所以理论上它已被正确清理,不是吗?
干杯。
答案 0 :(得分:2)
问题原来是Runnable
中的匿名postDelayed
。使用基本活动的内容视图的Runnable
函数调用此postDelayed()
,因此它是这样的:
@Override
protected void onResume() {
...
mCallback = new Runnable() { ... };
getContentView().postDelayed(mCallback, mDelay);
}
令人惊讶的是,此回调已在onPause()
中删除:
@Override
protected void onPause() {
...
getContentView().removeCallbacks(mCallback);
mCallback = null;
}
为什么这不能防止泄漏对我来说仍然是个谜。起初我尝试使用getContentView().getHandler().removeCallbacksAndMessages(null)
并修复了漏洞,然后应用程序在看似无关的地方完全分解了。
最后修复泄漏的是创建Handler
实例并在此处理程序上调用postDelayed()
和removeCallbacks()
。