2015-07-08 8 views
13

Ho registro blocchi:eccezione illegale androide quando finestra mostra

java.lang.IllegalArgumentException: View=com.android.internal.policy.impl.PhoneWindow$DecorView{21f9ba68 V.E..... R.....ID 0,0-1136,402} not attached to window manager 
at android.view.WindowManagerGlobal.findViewLocked(WindowManagerGlobal.java:402) 
at android.view.WindowManagerGlobal.removeView(WindowManagerGlobal.java:328) 
at android.view.WindowManagerImpl.removeViewImmediate(WindowManagerImpl.java:84) 
at android.app.Dialog.dismissDialog(Dialog.java:433) 
at android.app.Dialog.dismiss(Dialog.java:416) 
at ys.a(ConfirmationDialog.java:82) 
at ys.a(ConfirmationDialog.java:76) 
at **com.smarttech.kapp.SnapshotActivity.onOptionsItemSelected(SnapshotActivity.java:147)** 
at android.app.Activity.onMenuItemSelected(Activity.java:3036) 
at android.support.v4.app.FragmentActivity.onMenuItemSelected(FragmentActivity.java:373) 
at com.android.internal.policy.impl.PhoneWindow.onMenuItemSelected(PhoneWindow.java:1222) 
at com.android.internal.view.menu.MenuBuilder.dispatchMenuItemSelected(MenuBuilder.java:761) 
at com.android.internal.view.menu.MenuItemImpl.invoke(MenuItemImpl.java:155) 
at com.android.internal.view.menu.MenuBuilder.performItemAction(MenuBuilder.java:904) 
at com.android.internal.view.menu.MenuBuilder.performItemAction(MenuBuilder.java:894) 
at android.widget.ActionMenuView.invokeItem(ActionMenuView.java:611) 
at com.android.internal.view.menu.ActionMenuItemView.onClick(ActionMenuItemView.java:197) 
at android.view.View.performClick(View.java:5217) 
at android.view.View.onKeyUp(View.java:9663) 
at android.widget.TextView.onKeyUp(TextView.java:7047) 
at android.view.KeyEvent.dispatch(KeyEvent.java:3171) 
at android.view.View.dispatchKeyEvent(View.java:8876) 
at android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:1695) 
at android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:1695) 
at android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:1695) 
at android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:1695) 
at android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:1695) 
at com.android.internal.policy.impl.PhoneWindow$DecorView.superDispatchKeyEvent(PhoneWindow.java:2671) 
at com.android.internal.policy.impl.PhoneWindow.superDispatchKeyEvent(PhoneWindow.java:1787) 
at android.app.Activity.dispatchKeyEvent(Activity.java:2837) 
at com.android.internal.policy.impl.PhoneWindow$DecorView.dispatchKeyEvent(PhoneWindow.java:2549) 
at android.view.ViewRootImpl$ViewPostImeInputStage.processKeyEvent(ViewRootImpl.java:4661) 
at android.view.ViewRootImpl$ViewPostImeInputStage.onProcess(ViewRootImpl.java:4616) 
at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:4174) 
at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:4227) 
at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:4193) 
at android.view.ViewRootImpl$AsyncInputStage.forward(ViewRootImpl.java:4303) 
at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:4201) 
at android.view.ViewRootImpl$AsyncInputStage.apply(ViewRootImpl.java:4360) 
at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:4174) 
at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:4227) 
at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:4193) 
at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:4201) 
at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:4174) 
at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:4227) 
at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:4193) 
at android.view.ViewRootImpl$AsyncInputStage.forward(ViewRootImpl.java:4336) 
at android.view.ViewRootImpl$ImeInputStage.onFinishedInputEvent(ViewRootImpl.java:4500) 
at android.view.inputmethod.InputMethodManager$PendingEvent.run(InputMethodManager.java:2607) 
at android.view.inputmethod.InputMethodManager.invokeFinishedInputEventCallback(InputMethodManager.java:2201) 
at android.view.inputmethod.InputMethodManager.finishedInputEvent(InputMethodManager.java:2192) 
at android.view.inputmethod.InputMethodManager$ImeInputEventSender.onInputEventFinished(InputMethodManager.java:2584) 
at android.view.InputEventSender.dispatchInputEventFinished(InputEventSender.java:141) 
at android.os.MessageQueue.nativePollOnce(Native Method) 
at android.os.MessageQueue.next(MessageQueue.java:143) 
at android.os.Looper.loop(Looper.java:130) 
at android.app.ActivityThread.main(ActivityThread.java:6117) 
at java.lang.reflect.Method.invoke(Native Method) 
at java.lang.reflect.Method.invoke(Method.java:372) 
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1399) 
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1194) 

Questo è il codice laghetti L'alimento di dialogo che mostra l'attività snapshot:

@Override 
public boolean onOptionsItemSelected(MenuItem item) { 
    switch (item.getItemId()) { 
     case android.R.id.home: 
      finish(); 
      return true; 
     case R.id.snapshot_delete: 
      Log.d(TAG, "delete snapshot"); 
      **delete();** 
      return true; 
     case R.id.snapshot_share: 
      export(); 
      return true; 
    } 

    return super.onOptionsItemSelected(item); 
} 

private void delete() { 
    Log.d(TAG, "Delete snapshot"); 
    final int index = pager.getCurrentItem(); 
    ConfirmationDialog.prompt(this, R.string.delete_snapshot, R.string.delete_snapshot_confirmation, R.string.delete, android.R.string.cancel, new Runnable() { 
     @Override 
     public void run() { 
      snapshots.get(index).delete(); 
      loadSnapshots(); 
     } 
    }); 
} 

Questo incidente è molto difficile da riprodurre e che è tutte le informazioni che cosa ho. Qual è la ragione di questa eccezione? E come può essere riparato? Penso che il motivo è thread nel dialogo, ma non sono sicuro

public static void prompt(final Context context, int titleResourceId, int questionResourceId, int positiveButton, int negativeButton, final Runnable confirmedRunnable, final Runnable cancelledRunnable) { 
    closeDialog(); 
    DialogInterface.OnClickListener confirmed = new DialogInterface.OnClickListener() { 
     public void onClick(DialogInterface dialog, int whichButton) { 
      currentDialog = null; 
      confirmedRunnable.run(); 
     } 
    }; 
    DialogInterface.OnClickListener cancelled = new DialogInterface.OnClickListener() { 
     public void onClick(DialogInterface dialog, int whichButton) { 
      currentDialog = null; 
      if (cancelledRunnable != null) { 
       cancelledRunnable.run(); 
      } 
     }; 
    }; 
    currentDialog = new AlertDialog.Builder(context).setTitle(titleResourceId).setMessage(questionResourceId).setIcon(android.R.drawable.ic_dialog_alert).setPositiveButton(positiveButton, confirmed) 
      .setNegativeButton(negativeButton, cancelled).show(); 
    currentDialog.setCancelable(cancelled == null); 
    currentDialog.setCanceledOnTouchOutside(cancelled == null); 
} 

Questa è l'attuazione promt

+0

La ragione di ottenere questo tipo di eccezione è probabilmente legato alla 'context'. –

+0

penso ConfirmationDialog.prompt (........) shheid chanhe a ConfirmationDialog.show (........) –

+0

Ho aggiunto l'implementazione di promt – Pein

risposta

16

Il livello superiore del vostro stacktrace ti dice ciò che è sbagliato:

java.lang.IllegalArgumentException: View=com.android.internal.policy.impl.PhoneWindow$DecorView{21f9ba68 V.E..... R.....ID 0,0-1136,402} not attached to window manager 
at android.view.WindowManagerGlobal.findViewLocked(WindowManagerGlobal.java:402) 
at android.view.WindowManagerGlobal.removeView(WindowManagerGlobal.java:328) 
at android.view.WindowManagerImpl.removeViewImmediate(WindowManagerImpl.java:84) 
at android.app.Dialog.dismissDialog(Dialog.java:433) 
at android.app.Dialog.dismiss(Dialog.java:416) 

Stai chiamando congedo su una finestra di dialogo che al momento non viene più mostrata. Come in: la tua Attività/Frammento è probabilmente già distrutta quando chiami licenziamento (-> "non collegato al gestore di finestre").

[modifica] Un modo per risolvere questo problema è quello di verificare la presenza di activity.isFinishing() o fragment.isAdded()

+1

possiamo farlo in questo modo se (alertDialog! = Null && alertDialog.isShowing()) {alertDialog.dismiss();} ??? –

+2

Probabilmente è ancora meglio. –

+0

ok allora lo posterò come risposta –

3

Si prega di respingere come segue

if ((alertDialog != null) && alertDialog.isShowing()) 
     { 
      alertDialog.dismiss(); 
     } 
+9

anche con questo controllo prima di chiudere, viene lanciata un'eccezione. – arorak

1

Un modo semplice per chiudere in modo sicuro il dialogo è quello di verificare se la vista in cui è contenuta la finestra di dialogo è attualmente visualizzata prima di tentare di chiuderla. Sembra:

if (view.isShown()) { 
    dialog.dismiss() 
} 
0

Non vedo alcun motivo per cui l'intera app dovrebbe bloccarsi su qualcosa di simile. Mi sembra che un'eccezione a questo punto debba essere il risultato di un'attività già conclusa o qualcosa del genere. In entrambi i casi, suppongo che l'utente non stia più guardando la finestra di dialogo, quindi ho creato un'utilità semplice per chiudere silenziosamente i miei dialoghi.

import android.app.Dialog; 
import android.util.Log; 

import java.io.PrintWriter; 
import java.io.StringWriter; 

public class DialogUtil { 

    public static final String TAG = "DialogUtil"; 

    public static void safeDismiss(Dialog dialog) { 
     if (dialog != null && dialog.isShowing()) { 
      try { 
       dialog.dismiss(); 
      } catch (RuntimeException ex) { 
       StringWriter sw = new StringWriter(); 
       ex.printStackTrace(new PrintWriter(sw)); 
       Log.e(TAG, sw.toString()); 
      } 
     } 
    } 
} 
0

Suggerisco, si dovrebbe anche controllare se l'attività non è nullo.

if (activity != null && progressDialog != null && progressDialog.isShowing()) { 
       progressDialog.dismiss(); 
      } 
0

devo stesso problema, e ho sove il problema controllando:

if (alertDialog != null && alertDialog .isShowing() && !this.isFinishing()) 
{ 
    alertDialog .dismiss(); 
}