【问题标题】:Why this leaks on a rotation?为什么这会在旋转时泄漏?
【发布时间】:2012-11-04 14:09:01
【问题描述】:

我遇到了以下内存泄漏示例

package com.justinschultz.android;

import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.os.Bundle;

public class LeakedDialogActivity extends Activity {

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        AlertDialog.Builder builder = new AlertDialog.Builder(this);
        builder.setIcon(android.R.drawable.ic_dialog_alert);
        builder.setMessage("This dialog leaks!").setTitle("Leaky Dialog").setCancelable(false).setPositiveButton("Ok", new DialogInterface.OnClickListener()
        {
            public void onClick(DialogInterface dialog, int which) {}
        });

        AlertDialog alert = builder.create();
        alert.show();
    }
}

我不明白为什么它会在旋转时泄漏。我了解,当对话框仍在屏幕上时,会创建一个新活动(包含对旧活动的引用)。假设您关闭对话框并再次旋转。对最旧活动的引用不应该消失,从而允许回收内存吗?

【问题讨论】:

  • 你确定有内存泄漏吗?你检查堆增长了吗?
  • 是的,根据 LogCat 的说法。我找到了这个例子here。我有点理解为什么它是泄漏,但我认为 gc 可以在用户关闭对话框后回收它。

标签: java android memory-leaks


【解决方案1】:

AlertDialogs(如果在 Fragments 之外使用)应通过 onCreateDialog()/showDialog() 实例化以避免泄漏。

此实现已弃用,应替换为 DialogFragment,但对您有用:

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);

    showDialog(YOUR_DIALOG_ID);
}

@Override
protected Dialog onCreateDialog(int id) {
    switch(id) {
    case YOUR_DIALOG_ID:
        return new AlertDialog.Builder(LeakedDialogActivity.this)
        .setIcon(android.R.drawable.ic_dialog_alert)
        .setMessage("This dialog leaks!")
        .setTitle("Leaky Dialog")
        .setCancelable(false)
        .setPositiveButton("Ok", new DialogInterface.OnClickListener() {
            public void onClick(DialogInterface dialog, int which) {}
        })
        .create();
    }
    return super.onCreateDialog(id);
}

添加

当您不在onCreateDialog 中创建对话框时,它基本上不附加到(或拥有)活动,因此,它是生命周期。当 Activity 被销毁或重新创建时,Dialog 会维护对它的引用。

理论上,如果您使用setOwnerActivity() 并在onPause() 中关闭(我相信),则对话框不应泄漏。

就一般泄漏而言,我不确定您是否需要担心这个陷阱。对话框是一种特殊情况。

【讨论】:

  • 嗨,保罗,感谢您的回复!我发布的示例只是“教学”。我希望找出泄漏的原因,这样我就可以避免容易发生泄漏的做法。
猜你喜欢
  • 2019-02-09
  • 1970-01-01
  • 2011-12-19
  • 2013-04-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多