内存泄漏 - android.os.Message持有的Android活动

时间:2014-01-08 17:21:05

标签: java android memory-leaks

我正在开发一个应用程序,其中90%的活动都是从一个共同的活动继承而且所有这些活动都会泄漏,这意味着如果我从A->B开始,然后B->A({{1} }被调用),finish()的{​​{1}}被调用,但它仍然泄漏(用MAT检查)。

泄露的活动相当大(10MB~)所以经过几次来回移动应用程序崩溃了。

我已经检查了堆转储,并按照GC根的路径进行了泄漏活动,它们看起来像这样: enter image description here

所以我猜这是普通超类泄漏的东西。我已经检查过,当活动被破坏并且没有使用B时,所有的BroadcastReceivers和监听器都没有注册,也没有匿名的内部类可能导致泄漏(至少在我看来)。 / p>

泄漏的原因是什么?任何帮助都会非常感激。

修改

我发现有两段代码在注释掉活动时不再泄漏:

  1. 实例化onDestroy()的一些代码行。
  2. 使用匿名Handler致电ProgressDialog
  3. 在第一种情况下,对话框的postDelayed函数在销毁之前被调用,所以我不知道为什么这可能是问题。在第二种情况下,为Runnable中的dismiss()调用removeCallbacks,所以理论上它已被正确清理,不是吗?

    干杯。

1 个答案:

答案 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()