0

ダイアログの作成時にこのエラーが報告されることがありますが、私自身はエラーを経験しておらず、ダイアログでデータを送信しているため、すべてのユーザーに発生していないようです。私はアンドロイド2.2をテストしました。これがコードです。

private static final int DIALOG_CONTEST_ENTRY = 939321;

showDialog(DIALOG_CONTEST_ENTRY);

protected Dialog onCreateDialog(int id) {

    switch (id) {
    case DIALOG_CONTEST_ENTRY: 
        final Dialog dialog = new Dialog(this);
        dialog.setContentView(R.layout.contest_entry_dialog);
        dialog.setTitle(getString(R.string.ContestEntryDialogTitle));
        dialog.setCanceledOnTouchOutside(true);
        TextView text = (TextView) dialog.findViewById(R.id.contest_text); 
        text.setText(getString(R.string.ContestEntryDialogText));
        Button sendButton = (Button) dialog.findViewById(R.id.ButtonSend);
        Button cancelButton = (Button) dialog.findViewById(R.id.ButtonCancel);
        final EditText name = (EditText) dialog.findViewById(R.id.editName);
        final EditText email = (EditText) dialog.findViewById(R.id.editEmail);
        final TextView score = (TextView) dialog.findViewById(R.id.textScore);

        final Prefs prefs = new Prefs(xxxActivity.this);

        name.setText(prefs.ReadString("Name"));
        email.setText(prefs.ReadString("Email"));
        score.setText("Score: " + scoreCurrent);

        sendButton.setOnClickListener(new View.OnClickListener() {
            public void onClick(View v) {
                                            //Send form
                    dialog.dismiss();
                }
            }
        });
        cancelButton.setOnClickListener(new View.OnClickListener() {
            public void onClick(View v) {
                dialog.dismiss();
            }
        });
        dialog.show();
        return dialog;
    default:
        break;
    }
    return super.onCreateDialog(id);
}


<LinearLayout
  xmlns:android="http://schemas.android.com/apk/res/android"
   android:layout_width="match_parent"
  android:layout_height="match_parent" android:orientation="vertical" android:padding="10dp" android:background="#FFF">

<TextView
    android:id="@+id/contest_text"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="@string/ContestEntryDialogText"
    android:textColor="#000" />

<EditText
    android:id="@+id/editName"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:inputType="textPersonName" android:hint="Enter Name"/>

<EditText
    android:id="@+id/editEmail"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:inputType="textEmailAddress" android:hint="Enter Email">

    <requestFocus />
</EditText>
<TextView
    android:id="@+id/textScore"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="Score: " android:textSize="20dp"/>

<LinearLayout
    android:id="@+id/linearLayout1"
    android:layout_width="match_parent"
    android:layout_height="wrap_content" >

    <Button
        android:id="@+id/ButtonSend"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Send" />

    <Button
        android:id="@+id/ButtonCancel"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Cancel" />

</LinearLayout>

4

1 に答える 1

1

この同じ問題が発生した後 (onPause 内から removeDialog を呼び出しても確実に機能しないことがわかった)、機能しているように見える回避策を開発しました (確かにハックですが)。

antslava によって投稿された grepcode リンクに見られるように、メソッド performRestoreInstanceState で onRestoreInstanceState が restoreManagedDialogs の直前に呼び出され、Bundle savedInstanceState の同じインスタンスが渡されます。

final void performRestoreInstanceState(Bundle savedInstanceState) {
    onRestoreInstanceState(savedInstanceState);
    restoreManagedDialogs(savedInstanceState);
}

したがって、 onRestoreInstanceState メソッド内から restoreManagedDialogs に渡される Bundle savedInstanceState を変更する機会があります。

すべての管理対象ダイアログが復元されないようにするには、次の方法で onRestoreInstanceState を実装できます。

// This same variable is defined as private in the Activity class. I need
// access to it, so I redefine it here.
private static final String SAVED_DIALOGS_TAG = "android:savedDialogs";

@Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
    super.onRestoreInstanceState(savedInstanceState);
    final Bundle b = savedInstanceState.getBundle(SAVED_DIALOGS_TAG);
    if (null != b) {
        savedInstanceState.remove(SAVED_DIALOGS_TAG);
    }
}

これにより、キー「android:savedDialogs」によって参照されるバンドルがバンドルの savedInstanceState から削除され、その後、このキーが見つからないことが判明すると、restoreManagedDialogs への呼び出しがすぐに返されます。

private void restoreManagedDialogs(Bundle savedInstanceState) {
    final Bundle b = savedInstanceState.getBundle(SAVED_DIALOGS_TAG);
    if (b == null) {
        return;
    }
    ...
}

これにより、アクティビティの復元中に onCreateDialog が呼び出されなくなり、ダイアログが効果的に「非表示」になり、onCreateDialog から null を返さなければならないシナリオが発生しなくなります。

これは「万能」ソリューションではありませんが、私の要件を考えると、法案に適合しているようです。いくつかのプラットフォーム バージョン (1.6、2.1、2.2、2.2.2、および 4.0.3) の grepcode のコードを確認すると、これらの既存の実装を考えると、このソリューションは一貫して機能するはずです。

于 2012-04-05T03:06:42.157 に答える