Android RuntimeException onCreateDialog没有为id创建对话框

时间:2010-11-19 13:41:24

标签: android runtimeexception

我有一个应用程序可以显示和关闭几个Dialogs:

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

我在应用程序中玩了一下,当屏幕上没有任何对话框时,我按下菜单按钮,然后进入主安卓屏幕。

过了一会儿,我再次进入我的应用程序,有时,我得到这个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);

5 个答案:

答案 0 :(得分:11)

在API级别8中,onCreateDialog(int)deprecated,支持onCreateDialog(int,Bundle)。如果仅实现后一种方法并在API级别低于8的设备上运行应用程序,则会收到所描述的错误消息。

解决方案是实施onCreateDialog(int)

答案 1 :(得分:4)

对于SDK版本< 8,如果在onCreateDialog中返回null,则会出现异常java.lang.IllegalArgumentException。

答案 2 :(得分:2)

在遇到同样的问题(并发现从removeDialog内调用onPause无法可靠地工作)之后,我开发了一种似乎有效的解决方法(尽管它确实是一种黑客行为)。

grepcode link posted by antslava所示,在方法performRestoreInstanceState中,onRestoreInstanceStaterestoreManagedDialogs之前调用,并传递给Bundle savedInstanceState的同一个实例。

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

因此,有机会修改Bundle savedInstanceState方法中传递给restoreManagedDialogs的{​​{1}}。

为了防止恢复任何和所有托管对话框,可以通过以下方式实现onRestoreInstanceState

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的情况。< / p>

这不是“一刀切”的解决方案,但考虑到我的要求,似乎符合要求。通过查看grepcode中几个平台版本(1.6,2.1,2.2,2.2.2和4.0.3)的代码,看来这个解决方案应该在这些现有实现的情况下保持一致。

答案 3 :(得分:0)

您是否按照提交的here实施了OnCreateDialog?当您第一次调用showDialog(4)时,将调用OnCreateDialog(4),您需要创建对话框并从此方法返回它。

答案 4 :(得分:0)

您是否在onCreateDialog中正确返回了对话框?如果您在对话框创建中执行dialog.show()但返回其他对话框,则可能会得到类似的结果。

或者您正在对onPrepareDialog

中的对话框对象进行任何操作