Frage

habe ich eine Anwendung, die Sie zeigen können, und in der Nähe mehr Dialoge mit:

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

Ich spiele ein wenig mit der Anwendung und wenn kein jeder Dialog auf dem Bildschirm, drücke ich die Menü-Taste, und ich gehe auf die Haupt Android-Bildschirm.

Nach einer Weile gebe ich wieder in meine Anwendung und manchmal, ich diesen Runtime bekommen:

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

Jede Idee?

Vielen Dank.

UPDATE, weitere Informationen:

Die aktuelle onCreateDialog Implementierung ist:

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

Um diese Funktion aufzurufen, ich tun:

removeDialog(4);
showDialog(4);
War es hilfreich?

Lösung

Nach dem das gleiche Problem erlebt (und festgestellt, dass aus removeDialog onPause Aufruf nicht zuverlässig funktioniert), entwickelte ich eine Abhilfe, die Funktion scheint (obwohl es zugegebenermaßen ein Hack).

Wie in der grepcode Link gepostet von antslava , in Verfahren performRestoreInstanceState wird onRestoreInstanceState Recht vor restoreManagedDialogs genannt und ist die gleiche Instanz von Bundle savedInstanceState übergeben.

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

So gibt es Gelegenheit, die Bundle savedInstanceState zu ändern, die zu restoreManagedDialogs innerhalb der onRestoreInstanceState Methode übergeben wird.

Um zu verhindern, jegliche und alle verwalteten Dialoge gestellt wird, könnte man onRestoreInstanceState in der folgenden Art und Weise implementieren:

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

Dies bewirkt, dass die Bundle von Schlüssel "android:savedDialogs" verwiesen von Bundle savedInstanceState entfernt werden, die anschließend den Anruf zu restoreManagedDialogs bewirkt sofort zurück, wenn er feststellt, dass dieser Schlüssel nicht gefunden:

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

Dies wird dazu führen, onCreateDialog nicht genannt werden, während die Aktivität der Wiederherstellung effektiv „Versteck“ alle Dialoge, so das Szenario zu verhindern, wo man null von onCreateDialog auftritt zurückgeben muss.

Dies ist keine ‚one size fits all‘ Lösung, aber meine Anforderungen gegeben scheint es, die Rechnung zu passen. Durch die Überprüfung des Codes in grepcode für mehrere Plattform-Versionen (1.6, 2.1, 2.2, 2.2.2 und 4.0.3), scheint es, dass diese Lösung sollte konsequent diese bestehenden Implementierungen gegeben arbeiten.

Andere Tipps

In API-Ebene 8, onCreateDialog(int) WAS deprecated für onCreateDialog(int,Bundle). Wenn Sie nur die letztere Methode implementieren und die App auf einem Gerät mit einer API-Ebene niedriger als 8 laufen, erhalten Sie die beschriebene Fehlermeldung.

Die Lösung ist onCreateDialog(int) umzusetzen

Für SDK-Version <8, wenn Sie null in onCreateDialog Rückkehr erhalten Sie Exception java.lang.IllegalArgumentException.

Haben Sie OnCreateDialog implementiert, wie präsentiert hier ? Wenn Sie showdialog (4) zum ersten Mal aufrufen, wird OnCreateDialog (4) aufgerufen werden und müssen Sie den Dialog erstellen und von dieser Methode zurück.

Kehren Sie richtig den Dialog in onCreateDialog? Wenn Sie tun dialog.show sind () im Dialog erstellen, aber einen anderen Dialog zurückkehren Sie vielleicht ein Ergebnis wie das bekommen können.

Oder tun Sie jede Art von Manipulation in dem Dialog-Objekts in onPrepareDialog

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top