2010-11-19 5 views
6

에 대한 대화 상자를 작성하지 않은 I했습니다 당신이 보여와 여러 대화 상자를 닫을 수있는 응용 프로그램 : 안드로이드의 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 

어떤 생각을?

대단히 감사합니다.

UPDATE 자세한 내용은 :

현재이 onCreateDialog 구현은 다음과 같습니다

removeDialog(4); 
showDialog(4); 

답변

2

에서 removeDialog을 호출하는 것이 안정적으로 작동하지 않는다는 사실을 발견 한 후, 작동하는 해결 방법을 개발했습니다. (해킹 일지라도). 방법 performRestoreInstanceState에서 grepcode link posted by antslava에서 보듯

onRestoreInstanceState 바로 전에 restoreManagedDialogs이라고하며 Bundle savedInstanceState의 동일한 인스턴스를 통과한다.

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

따라서, onRestoreInstanceState 방법 내에서 restoreManagedDialogs에 전달되는 Bundle savedInstanceState을 수정할 수있는 기회가있다.이 이후에 호출이 발생 Bundle savedInstanceState에서 제거 할 키 "android:savedDialogs"가 참조하는 Bundle 원인

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

:

하나는 다음과 같은 방법으로 onRestoreInstanceState을 구현할 수, 복원되는 일체의 관리 대화 상자를 방지하기 위해

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

이가 발생합니다 : 그것은이 키를 찾을 수 없음을 발견하면 restoreManagedDialogs에 즉시 반환은 활동을 복원하는 동안 호출되지 않아 효과적으로 대화를 숨김으로써 nullonCreateDialog에서 반환해야하는 시나리오를 방지합니다.

이것은 하나의 크기에 맞는 해결책은 아니지만 제 요구 사항을 감안할 때 청구서에 맞는 것으로 보입니다. 여러 플랫폼 버전 (1.6, 2.1, 2.2, 2.2.2 및 4.0.3)에 대한 grepcode의 코드를 검토하면이 기존 솔루션이 일관되게 작동해야합니다.

0

here을 선물로 당신이 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; 
} 

? showDialog (4)를 처음 호출하면 OnCreateDialog (4)가 호출되며 대화 상자를 만들어이 메서드에서 반환해야합니다.

+0

그래, 모든 코드가 완벽하게 작동합니다. 응용 프로그램이 어디에서나 충돌하지 않습니다. 나는 현재 다이얼로그가 팝업되고 완벽하게 닫히는 것을 보았다. 응용 프로그램을 다시 시작하면 문제가 임의로 시작됩니다. – zegnus

0

제대로 대화 하시겠습니까? onCreateDialog? 대화 상자에서 dialog.show()를 수행했지만 다른 대화 상자를 반환하면 비슷한 결과를 얻을 수 있습니다.

또는 당신은 onCreateDialog(int)onCreateDialog(int,Bundle) 찬성 deprecated했다, API 레벨 8에 onPrepareDialog

+0

그래, 대화 상자는 Builder b = new AlertDialog.Builder (this); ...; return b.create(); 매번 대화 상자를 표시 할 때마다 대화 상자의 내용이 변경되므로 removeDialog (4)를 호출 한 다음 showDialog (4)를 호출합니다. 나는 onPrepareDialog를 오버라이드하지 않는다 ... – zegnus

11

의 대화 개체에 조작의 어떤 종류를하고 있습니다. 후자의 방법 만 구현하고 API 레벨이 8보다 낮은 기기에서 앱을 실행하면 설명 된 오류 메시지가 표시됩니다.

이 솔루션은 당신이 onCreateDialog에서 null을 반환하면 예외 java.lang.IllegalArgumentException를 얻을 경우, SDK 버전 < 8의 onCreateDialog(int)

+0

안녕하세요 mndrix, 내 현재 대상은 8이지만 내 minversion은 3입니다. 내 onCreateDialog (int) 구현으로 게시물을 업데이트했습니다. 감사! – zegnus

4

을 구현하는 것입니다.

+0

좋아, 그럴 수있어. 내 대화 상자 번호 4 안에는 내부 검사가 있었고 실패하면 null을 반환합니다. 이것이 오류 일 수 있습니다. 공식 문서에서 null을 반환하는 옵션이 있지만 http://developer.android.com/guide/topics/ui/dialogs.html 문제는 이전에 앱이 대화 상자를 표시 할 수 있다고 생각합니다. , 사용자가 다른 앱으로 이동 한 다음 앱이 돌아 오면 앱은 대화 상자를 복원하려고 시도하지만 이번에는 null을 반환합니다. 나는 그것을 검사 할 것이다, 고마워! – zegnus

+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. 이 메서드는 대화 상자를 mManagedDialogs에서 제거하기 때문에 해결 방법은 removeDialog 메서드를 사용해야합니다. – antslava