web-dev-qa-db-fra.com

exception illégale Android lorsque la boîte de dialogue est affichée

J'ai un journal d'accident:

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)

Voici un code permettant d’afficher une boîte de dialogue dans l’activité de capture instantanée:

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

Ce crash est très difficile à reproduire et c’est toute l’information dont je dispose Quelle est la raison de cette exception? Et comment il peut être corrigé? Je pense que la raison en est un fil dans le dialogue, mais je ne suis pas sûr

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

C'est l'implémentation promt

16
Pein

Le niveau supérieur de votre stacktrace vous dit ce qui ne va pas:

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)

Vous appelez la suppression dans une boîte de dialogue qui ne s'affiche plus .. .. Comme dans: votre activité/fragment est peut-être déjà détruit lorsque vous appelez la suppression (-> "non attaché au gestionnaire de fenêtres").

[edit] Un moyen de remédier à cela est de vérifier activity.isFinishing () ou fragment.isAdded ()

18
Ken Van Hoeylandt

S'il vous plaît rejeter comme suit

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

Un moyen simple de fermer votre boîte de dialogue en toute sécurité consiste à vérifier si la vue contenue dans la boîte de dialogue est actuellement affichée avant de tenter de la fermer. Cela ressemble à:

if (view.isShown()) {
    dialog.dismiss()
}
1
degs

Je ne vois aucune raison pour laquelle l'application entière devrait se bloquer sur quelque chose comme ça. Il me semble qu’une exception à ce stade doit être le résultat d’une activité déjà terminée ou de quelque chose du genre. Dans les deux cas, je suppose que l'utilisateur ne regarde plus la boîte de dialogue. J'ai donc créé un utilitaire simple pour fermer mes boîtes de dialogue en mode silencieux.

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());
            }
        }
    }
}
1
Bjørn Stenfeldt

Je suggère, vous devriez également vérifier si l'activité n'est pas nulle.

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

J'ai le même problème, Et j'ai résolu ce problème en vérifiant:

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