4

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

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();
    }
}

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

4

1 回答 1

3

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

就一般泄漏而言,我不确定您是否必须担心这个问题。对话框是一种特殊情况。

于 2012-11-04T14:45:54.493 回答