6

私はあなたがいくつかのダイアログを表示して閉じることができるアプリケーションを持っています:

showDialog(...)
removeDialog(...)

アプリケーションで少し遊んで、画面にダイアログが表示されていないときにメニューボタンを押して、Androidのメイン画面に移動します。

しばらくすると、アプリケーションに再度入ると、次のRuntimeExceptionが発生することがあります。

java.lang.IllegalArgumentException: Activity#onCreateDialog did not create a dialog for id 4
    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2596)
    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2621)
    at android.app.ActivityThread.access$2200(ActivityThread.java:126)
    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1932)
    at android.os.Handler.dispatchMessage(Handler.java:99)
    at android.os.Looper.loop(Looper.java:123)
    at android.app.ActivityThread.main(ActivityThread.java:4595)
    at java.lang.reflect.Method.invokeNative(Native Method)
    at java.lang.reflect.Method.invoke(Method.java:521)
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:860)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:618)
    at dalvik.system.NativeStart.main(Native Method)
Caused by: java.lang.IllegalArgumentException: Activity#onCreateDialog did not create a dialog for id 4
    at android.app.Activity.createDialog(Activity.java:878)
    at android.app.Activity.restoreManagedDialogs(Activity.java:867)
    at android.app.Activity.performRestoreInstanceState(Activity.java:815)
    at android.app.Instrumentation.callActivityOnRestoreInstanceState(Instrumentation.java:1096)
    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2565)
    ... 11 more

何か案が?

どうもありがとうございます。

更新、詳細情報:

現在のonCreateDialogの実装は次のとおりです。

protected Dialog onCreateDialog(int id){
 Builder b = new AlertDialog.Builder(this);
 if(id == 4){
  b.setMessage(...);
  b.setItems(items, new DialogInterface.OnClickListener(){
   public void onClick(DialogInterface dialog, int which){
    Intent i = new Intent(Current.this, Another.class);
    startActivity(i);
   }
  });
  return b.create();
 }
 return null;
}

この関数を呼び出すために、私は次のことを行います。

removeDialog(4);
showDialog(4);
4

5 に答える 5

11

API レベル 8 では、onCreateDialog(int)が優先され、廃止されonCreateDialog(int,Bundle)ました。後者の方法のみを実装し、API レベルが 8 未満のデバイスでアプリを実行すると、説明されているエラー メッセージが表示されます。

解決策は実装することですonCreateDialog(int)

于 2011-01-06T21:33:18.260 に答える
4

SDK バージョン < 8 の場合、onCreateDialog で null を返すと、例外 java.lang.IllegalArgumentException が発生します。

于 2011-01-28T13:01:37.593 に答える
2

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

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

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

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

すべての管理対象ダイアログが復元されないようにする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);
    }
}

これにより、Bundle参照されたキー"android:savedDialogs"が から削除されます。これにより、このキーが見つからないことが判明するBundle savedInstanceStateと、 の呼び出しがすぐに返されます。restoreManagedDialogs

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

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

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

于 2012-03-28T16:31:27.823 に答える
0

ここに示されているように OnCreateDialog を実装しましたか? 初めて showDialog(4) を呼び出すと、OnCreateDialog(4) が呼び出され、ダイアログを作成してこのメ​​ソッドから返す必要があります。

于 2010-11-19T13:45:13.673 に答える
0

でダイアログを正しく返していますonCreateDialogか? dialog create で dialog.show() を実行し、他のダイアログを返す場合、おそらくそのような結果が得られる可能性があります。

または、ダイアログオブジェクトで何らかの操作を行っていますか?onPrepareDialog

于 2010-11-19T15:59:52.627 に答える