Pein Pein - 26 days ago 7
Android Question

android illegal exception when dialog is showing

I have crash log:

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)


This is soruce code of showing dialog in snapshot activity:

@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();
}
});
}


This crash is very hard to reproduce and it is all information what I have.
What is a reason of this exception?
And How it can be fixed?
I think the reason is thread in dialog, but I'm not sure

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


This is promt implementation

Answer

The top level of your stacktrace is telling you what is wrong:

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)

You are calling dismiss on a dialog that is currently not being shown anymore. As in: your Activity/Fragment is possibly already destroyed when you call dismiss (-> "not attached to window manager").

[edit] One way to fix this is to check for activity.isFinishing() or fragment.isAdded()

Comments