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 (フラグメントの外部で使用する場合) は、リークを回避するために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 に答える