2010-11-19 50 views
6

創建一個對話框我有一個應用程序,它可以顯示和關閉幾個對話框有:的Android RuntimeException的onCreateDialog沒有爲ID

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

回答

2

在遇到同樣的問題(並且發現從內部調用removeDialog無法可靠地工作)後,我開發了一種似乎起作用的解決方法(雖然它的確是黑客)。

可以看出在grepcode link posted by antslava,在方法performRestoreInstanceStateonRestoreInstanceState被稱爲右側前restoreManagedDialogs,並通過了Bundle savedInstanceState相同的實例。

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

因此,機會來修改傳遞到restoreManagedDialogsonRestoreInstanceState方法中的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"引用的BundleBundle 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中的代碼,看起來這個解決方案應該在給定這些現有實現的情況下始終如一地工作。

0

你有沒有實現OnCreateDialog所呈現here?當您第一次調用showDialog(4)時,OnCreateDialog(4)將被調用,您需要創建對話框並從此方法返回它。

+0

是的,所有的代碼工作得很好。應用程序不會在任何地方崩潰。我目前正在觀看完美彈出對話框。當我重新啓動應用程序時,問題隨機開始。 – zegnus 2010-11-19 15:42:44

0

您是否正確返回對話框onCreateDialog?如果你在對話框中創建dialog.show(),但返回一些其他對話框,你可能會得到這樣的結果。

或者,您在onPrepareDialog

+0

是的,這個對話框是用Builder生成的b = new AlertDialog.Builder(this); ...;返回b.create();每當我顯示對話框時,我會調用removeDialog(4),然後showDialog(4),因爲對話框的內容會發生變化。我不重寫onPrepareDialog ... – zegnus 2010-11-22 12:30:10

11

在API級別8做任何形式的操縱,在對話框的對象,onCreateDialog(int)贊成的onCreateDialog(int,Bundle)deprecated。如果僅實現後一種方法並在API級別低於8的設備上運行應用程序,則會出現描述的錯誤消息。

的解決方案是實現onCreateDialog(int)

+0

嗨mndrix,我目前的目標是8,但我的minversion是3.我已經用我的onCreateDialog(int)實現更新了這篇文章。謝謝! – zegnus 2011-01-07 10:49:45

4

對於SDK版本< 8,如果你在onCreateDialog返回null你會得到異常java.lang.IllegalArgumentException異常。

+0

太好了,可能是那個。在我的4號對話框中,我進行了內部檢查,如果失敗,它將返回null。我認爲這可能是錯誤。雖然在官方文檔中,可以選擇返回null http://developer.android.com/guide/topics/ui/dialogs.html,但我認爲問題在於之前的應用程序能夠顯示對話框,那麼用戶轉到另一個應用程序,當他返回時,應用程序會嘗試恢復對話框,但這次返回null。我會檢查它,謝謝! – zegnus 2011-01-29 11:58:29

+1

在這裏你可以看到它http://grepcode.com/file/repository.grepcode.com/java/ext/com.google.android/android/2.1_r2/android/app/Activity.java#Activity.createDialog%28java .lang.Integer%2Candroid.os.Bundle%29。爲了修復它,你需要使用方法removeDialog,因爲這個方法從mManagedDialogs中移除你的對話框。 – antslava 2011-01-31 09:33:06

相關問題