java.lang.IllegalArgumentException: Ansicht nicht an Fenstermanager angehängt

148

Ich habe eine Aktivität, die AsyncTask startet und den Fortschrittsdialog für die Dauer des Vorgangs anzeigt. Die Aktivität wird als NICHT durch Drehen oder Schieben der Tastatur neu erstellt deklariert.

    <activity android:name=".MyActivity" 
              android:label="@string/app_name"
              android:configChanges="keyboardHidden|orientation"
              >
        <intent-filter>
        </intent-filter>
    </activity>

Sobald die Aufgabe abgeschlossen ist, entlasse ich den Dialog, aber auf einigen Telefonen (Framework: 1.5, 1.6) wird ein solcher Fehler ausgegeben:

java.lang.IllegalArgumentException: View not attached to window manager
    at android.view.WindowManagerImpl.findViewLocked(WindowManagerImpl.java:356)
    at android.view.WindowManagerImpl.removeView(WindowManagerImpl.java:201)
    at android.view.Window$LocalWindowManager.removeView(Window.java:400)
    at android.app.Dialog.dismissDialog(Dialog.java:268)
    at android.app.Dialog.access$000(Dialog.java:69)
    at android.app.Dialog$1.run(Dialog.java:103)
    at android.app.Dialog.dismiss(Dialog.java:252)
    at xxx.onPostExecute(xxx$1.java:xxx)

Mein Code lautet:

final Dialog dialog = new AlertDialog.Builder(context)
    .setTitle("Processing...")
    .setCancelable(true)
    .create();

final AsyncTask<MyParams, Object, MyResult> task = new AsyncTask<MyParams, Object, MyResult>() {

    @Override
    protected MyResult doInBackground(MyParams... params) {
        // Long operation goes here
    }

    @Override
    protected void onPostExecute(MyResult result) {
        dialog.dismiss();
        onCompletion(result);
    }
};

task.execute(...);

dialog.setOnCancelListener(new OnCancelListener() {
    @Override
    public void onCancel(DialogInterface arg0) {
        task.cancel(false);
    }
});

dialog.show();

Nach dem, was ich gelesen ( http://bend-ing.blogspot.com/2008/11/properly-handle-progress-dialog-in.html ) und in Android-Quellen gesehen habe, scheint es die einzig mögliche Situation zu sein, dies zu erreichen Ausnahme ist, wenn die Aktivität zerstört wurde. Aber wie ich bereits erwähnt habe, verbiete ich die Erholung von Aktivitäten für grundlegende Ereignisse.

Vorschläge sind daher sehr willkommen.

alex2k8
quelle
1
Diese Frage hat viele Antworten. Wenn Ihnen eine davon geholfen hat, wählen Sie sie bitte als die richtige Antwort aus.
Parag Kadam

Antworten:

227

Manchmal wird dieser Fehler auch angezeigt, wenn ich den Dialog schließe und die Aktivität mit der onPostExecute-Methode beende. Ich denke, manchmal wird die Aktivität beendet, bevor der Dialog erfolgreich beendet wird.

Einfache und dennoch effektive Lösung, die für mich funktioniert

@Override
protected void onPostExecute(MyResult result) {
    try {
        if ((this.mDialog != null) && this.mDialog.isShowing()) {
            this.mDialog.dismiss();
        }
    } catch (final IllegalArgumentException e) {
        // Handle or log or ignore
    } catch (final Exception e) {
        // Handle or log or ignore
    } finally {
        this.mDialog = null;
    }  
}
Damjan
quelle
44
Einfache Lösung? Ja. Wirksam? Vielleicht in diesem Fall. Würde ich es empfehlen? NEIN! Schlucken Sie nicht ALLE Ausnahmen! Ich würde nicht einmal die IllegalArgumentException abfangen, sondern nach einer anderen Lösung suchen.
Simon Forsberg
6
Weil normalerweise leere Try-Catches eine schlechte Idee sind ... Obwohl es manchmal das Richtige sein kann.
Thomas
3
@Damjan Mit Ihrer Antwort schlagen Sie den Fangtyp Exception vor. Nun, das ist eine schlechte Praxis von Google. Sie können hier darüber lesen: Keine generische Ausnahme abfangen .
Yaniv
17
Ich halte dies für eine effektive Lösung. Im Allgemeinen sollten wir dies nicht tun, aber da das Android Framework keine einfache Überprüfung für uns bietet, müssen wir ungewöhnliche Methoden anwenden. Wenn der isShowing () -Aufruf eines Dialogfelds wie erwartet funktioniert, benötigen wir diese Art von Hack nicht.
SXC
1
schnelle Lösung, bis etwas Besseres gefunden wird
Rohit Tigga
12

Hier ist meine "kugelsichere" Lösung, die alle guten Antworten zusammenfasst, die ich zu diesem Thema gefunden habe (danke an @Damjan und @Kachi). Hier wird die Ausnahme nur verschluckt, wenn alle anderen Erkennungsmethoden nicht erfolgreich waren. In meinem Fall muss ich den Dialog automatisch schließen und dies ist die einzige Möglichkeit, die App vor einem Absturz zu schützen. Ich hoffe es hilft dir! Bitte stimmen Sie ab und hinterlassen Sie Kommentare, wenn Sie Anmerkungen oder eine bessere Lösung haben. Danke dir!

public void dismissWithCheck(Dialog dialog) {
        if (dialog != null) {
            if (dialog.isShowing()) {

                //get the Context object that was used to great the dialog
                Context context = ((ContextWrapper) dialog.getContext()).getBaseContext();

                // if the Context used here was an activity AND it hasn't been finished or destroyed
                // then dismiss it
                if (context instanceof Activity) {

                    // Api >=17
                    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
                        if (!((Activity) context).isFinishing() && !((Activity) context).isDestroyed()) {
                            dismissWithTryCatch(dialog);
                        }
                    } else {

                        // Api < 17. Unfortunately cannot check for isDestroyed()
                        if (!((Activity) context).isFinishing()) {
                            dismissWithTryCatch(dialog);
                        }
                    }
                } else
                    // if the Context used wasn't an Activity, then dismiss it too
                    dismissWithTryCatch(dialog);
            }
            dialog = null;
        }
    }

    public void dismissWithTryCatch(Dialog dialog) {
        try {
            dialog.dismiss();
        } catch (final IllegalArgumentException e) {
            // Do nothing.
        } catch (final Exception e) {
            // Do nothing.
        } finally {
            dialog = null;
        }
    }
Ivo Stoyanov
quelle
1
sehr gute Lösung! Die Einstellung dialog = nullhat keine Auswirkung. Und StatusEventDialogsollte nur lesen Dialog.
Hgoebl
1
StatusEventDialog sollte in Dialog geändert werden.
Sreekanth Karumanaghat
Diese Antwort sollte die akzeptierte sein, sehr gut verarbeitet
Blueware
Ich verstehe, dass Sie "korrekt" sein und nur try / catch isDestroyed()verwenden möchten, falls dies nicht verfügbar ist, aber für praktische Zwecke wäre es nicht dasselbe, nur try / catch immer zu verwenden?
Zundi
11

Möglicherweise habe ich eine Problemumgehung.

Hatte das gleiche Problem, bei dem ich viele Elemente (über das Dateisystem) in ein ListViewvia ein lade AsyncTask. Hatte das onPreExecute()Auslösen eines ProgressDialog, und dann beide onPostExecute()und onCancelled()(aufgerufen, wenn die Aufgabe explizit über abgebrochen wird AsyncTask.cancel()) Schließen über .cancel().

Ich habe den gleichen Fehler "java.lang.IllegalArgumentException: Ansicht nicht an Fenstermanager angehängt" erhalten, als ich den Dialog in der onCancelled()Methode von beendet habe AsyncTask(ich hatte dies in der hervorragenden Shelves-App gesehen ).

Die Problemumgehung bestand darin, ein öffentliches Feld zu erstellen, das Folgendes AsyncTaskenthält ProgressDialog:

public ProgressDialog mDialog;

Dann in , onDestroy()wenn ich meine stornieren AsyncTask, kann ich töten auch den zugehörigen Dialog über:

AsyncTask.mDialog.cancel();

Der Aufruf AsyncTask.cancel()auslöst onCancelled()in dem AsyncTask, aber aus irgendeinem Grunde von der Zeit , diese Methode aufgerufen wird, wird die Ansicht bereits zerstört und damit der Dialog Cancelling versagt.

Paul Mennega
quelle
Ich finde die UserTask-Implementierung einfach hervorragend, wie @Paul erwähnt hat. Der Quellcode ist hier: code.google.com/p/shelves/source/browse/trunk/Shelves/src/org/…
Evi Song
Der Anwendungsfall befindet sich zwar im selben Projekt: code.google.com/p/shelves/source/browse/trunk/Shelves/src/org/…
Evi Song
9

Hier ist die richtige Lösung zur Lösung dieses Problems:

public void hideProgress() {
    if(mProgressDialog != null) {
        if(mProgressDialog.isShowing()) { //check if dialog is showing.

            //get the Context object that was used to great the dialog
            Context context = ((ContextWrapper)mProgressDialog.getContext()).getBaseContext();

            //if the Context used here was an activity AND it hasn't been finished or destroyed
            //then dismiss it
            if(context instanceof Activity) { 
                if(!((Activity)context).isFinishing() && !((Activity)context).isDestroyed()) 
                    mProgressDialog.dismiss();
            } else //if the Context used wasnt an Activity, then dismiss it too
                mProgressDialog.dismiss();
        }
        mProgressDialog = null;
    }
}

Anstatt alle Ausnahmen blind abzufangen, behebt diese Lösung die Ursache des Problems: Der Versuch, einen Dialog zu verkleinern, wenn die zum Initialisieren des Dialogs verwendete Aktivität bereits abgeschlossen ist. Ich arbeite an meinem Nexus 4 mit KitKat, sollte aber für alle Android-Versionen funktionieren.

Kachi
quelle
3
isDestroyederfordert API 17+
Androiderson
Warum müssen Sie mProgressDialog auf null setzen? Hängt das mit einem Speicherverlust zusammen? Könnten Sie bitte erklären?
Pawan
@Pawan, es ist ein Implementierungsdetail auf meiner Seite. Es ist nicht erforderlich, es ist nur die Art und Weise, wie die Funktion in dieser Klasse funktioniert. Nachdem ein Fortschrittsdialog ausgeblendet wurde, habe ich ihn auf null gesetzt. Wenn ein Benutzer einen anderen Fortschrittsdialog anzeigen möchte, wird eine neue Instanz instanziiert.
Kachi
Auf jeden Fall! ((Aktivitäts-) Kontext) .isFinishing () ist erforderlich, danke! :)
Daniel Krzyczkowski
5

Ich stimme einer Meinung von 'Damjan' zu.
Wenn Sie viele Dialoge verwenden, sollten Sie alle Dialoge in onDestroy () oder onStop () schließen.
In diesem Fall können Sie möglicherweise die Häufigkeit "java.lang.IllegalArgumentException: Ausnahme, die nicht an den Fenstermanager angehängt ist" reduzieren.

@Override
protected void onDestroy() {
    Log.d(TAG, "called onDestroy");
    mDialog.dismiss();
    super.onDestroy();
}



aber wenig überschreiten ...
um es klarer zu machen, verhindern Sie, dass nach dem Aufruf von onDestroy ein Dialogfeld angezeigt wird.
Ich benutze nicht wie unten. aber es ist klar.

private boolean mIsDestroyed = false;

private void showDialog() {
    closeDialog();

    if (mIsDestroyed) {
        Log.d(TAG, "called onDestroy() already.");
        return;
    }

    mDialog = new AlertDialog(this)
        .setTitle("title")
        .setMessage("This is DialogTest")
        .setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
            public void onClick(DialogInterface dialog, int which) {
                dialog.dismiss();
            }
        })
        .create();
    mDialog.show();
}

private void closeDialog() {
    if (mDialog != null) {
        mDialog.dismiss();
    }
}

@Override
protected void onDestroy() {
    Log.d(TAG, "called onDestroy");
    mIsDestroyed = true;
    closeDialog();
    super.onDestroy();
}


Viel Glück!

Hogun
quelle
Ich werde es immer vorziehen, leere Fangblöcke zu vermeiden. einen Versuch wert, aber da dieser Fehler schwer zu erzeugen ist, wird nur die Zeit zeigen, ob er tatsächlich funktioniert. Danke trotzdem.
Dror Fichman
Was sind leere Fangblöcke? Ich benutze Try / Catch nicht. Eine mIsDestroyed-Variable funktioniert nicht mehr. Wenn Sie jedoch in Code schreiben, den dieser Dialog nach einigen Arbeiten in einem anderen Thread anzeigt, benötigen Sie möglicherweise diese Variable. Wenn ein anderer Thread funktioniert und die Aktivität beendet ist, können Sie sich diese Ausnahme ansehen.
Hogun
Ich hatte das gleiche Problem und als ich @Override public void onPause () {if (dialog! = Null) dialog.dismiss () hinzufügte; super.onPause (); } bis heute habe ich diesen Fehler nicht ... also denke ich, es ist das gleiche wie Ihre Antwort und es ist wirklich nützlich
Chris Sim
@ ChrisSim Hallo! onPuase () und onDestroy () sind defference. Wenn Activity onPuase ist, wird der Dialog geschlossen. und wenn Sie die App ausführen, wird Dialog nicht angezeigt. willst du es
Hogun
@Hogun Ja natürlich, ich meine die gleiche Idee, ich schließe den Dialog bei Pause statt bei Zerstörung, weil ich ihn bei Pause brauche, nicht bei Zerstörung. Zweitens schließe ich es nur, wenn es nicht null ist. Vielen Dank, dass Sie dies anderen erklärt haben.
Chris Sim
4

Benutze das.

if(_dialog!=null && _dialog.isShowing())
_dialog.dismiss();
Pralabh Jain
quelle
2
Es ist fast die gleiche Lösung, die @Damjan vorgeschlagen hat.
Yury
28
Dies reicht nicht aus, die IllegalArgumentException tritt bei dieser Prüfung weiterhin auf.
Murphy
Ich habe die gleiche Lösung gemacht, weiß aber immer noch nicht, ob sie effektiv ist. Einziger Unterschied, ich habe zwei verschachtelt, um sicherzugehen, dass der zweite Teil .isShowing () nicht ausgewertet wird, wenn er null ist.
Nick
2
Dies reicht nicht aus.
Trante
1
@Nick: ifIn solchen Fällen ist es nicht erforderlich, mehrere zu verschachteln. Der Java- &&Operator hat eine verzögerte Auswertung (auch Kurzschluss genannt), was bedeutet, dass der 2. Operand nicht ausgewertet wird, wenn der erste auswertet false(was das Ergebnis von bedeutet das &&wird falsesowieso immer sein , daher "faule" auswertung). Ebenso ||wird sein 2. Operand nicht ausgewertet, wenn der erste zu ausgewertet wird true. Hinweis: Die Operatoren &und |haben dieses Verhalten nicht und werten daher immer beide Operanden aus.
Matthias
3

Ich hatte das gleiche Problem, Sie können es lösen durch:

@Override
protected void onPostExecute(MyResult result) {
    try {
        if ((this.mDialog != null) && this.mDialog.isShowing()) {
            this.mDialog.dismiss();
        }
    } catch (final IllegalArgumentException e) {
        // Handle or log or ignore
    } catch (final Exception e) {
        // Handle or log or ignore
    } finally {
        this.mDialog = null;
    }  
}
Spacebiker
quelle
2

Ich denke, Ihr Code ist korrekt im Gegensatz zu der anderen vorgeschlagenen Antwort. onPostExecute wird auf dem UI-Thread ausgeführt. Das ist der springende Punkt bei AsyncTask - Sie müssen sich keine Gedanken über den Aufruf von runOnUiThread machen oder sich mit Handlern befassen. Darüber hinaus kann entlassen () laut den Dokumenten sicher von jedem Thread aus aufgerufen werden (nicht sicher, ob dies die Ausnahme war).

Vielleicht ist es ein Zeitproblem, bei dem dialog.dismiss () aufgerufen wird, nachdem die Aktivität nicht mehr angezeigt wird?

Was ist mit dem Testen, was passiert, wenn Sie den setOnCancelListener auskommentieren und dann die Aktivität beenden, während die Hintergrundaufgabe ausgeführt wird? Dann versucht Ihr onPostExecute, einen bereits entlassenen Dialog zu schließen. Wenn die App abstürzt, können Sie wahrscheinlich nur überprüfen, ob der Dialog geöffnet ist, bevor Sie ihn schließen.

Ich habe genau das gleiche Problem, also werde ich es im Code ausprobieren.

Brandon O'Rourke
quelle
Ich habe mir auch dimiss () Code angesehen, und tatsächlich kann er sicher von jedem Thread aus aufgerufen werden. Übrigens, ich habe ein Problem mit dem Testen, da dieses Problem auf den Telefonen der Benutzer auftritt und ich es nie selbst reproduzieren konnte :-( Also versuchte ich es herauszufinden, indem ich Code analysierte ... Nach dem Timing. Ich dachte darüber nach, Ich kann mir aber keine Situation vorstellen, in der die Aktivität vor dem Dialog geschlossen werden kann. Wenn ZURÜCK gedrückt wird, wird der Dialog zuerst abgebrochen. Und die automatische Neuerstellung der Aktivität wird durch die Manifestdatei verboten, kann aber möglicherweise trotzdem wie neu erstellt werden Ich weiß, wenn Sie etwas finden!
Alex2k8
2

Alex,

Ich könnte mich hier irren, aber ich vermute, dass mehrere Telefone in freier Wildbahn einen Fehler aufweisen, der dazu führt, dass sie bei Anwendungen, die als statisch ausgerichtet markiert sind, die Ausrichtung ändern. Dies passiert ziemlich oft auf meinem persönlichen Telefon und auf vielen Testtelefonen, die unsere Gruppe verwendet (einschließlich Droide, n1, g1, Held). Normalerweise legt sich eine App, die als statisch ausgerichtet (möglicherweise vertikal) markiert ist, für ein oder zwei Sekunden in horizontaler Ausrichtung an und wechselt dann sofort zurück. Das Endergebnis ist, dass Sie darauf vorbereitet sein müssen, auch wenn Sie nicht möchten, dass Ihre App die Ausrichtung ändert. Ich weiß nicht, unter welchen genauen Bedingungen dieses Verhalten reproduziert werden kann. Ich weiß nicht, ob es für eine Android-Version spezifisch ist. Ich weiß nur, dass ich es schon oft gesehen habe :(

Ich würde empfehlen, die in dem von Ihnen geposteten Link bereitgestellte Lösung zu verwenden , die vorschlägt, die Activity onCreateDialog-Methode zu überschreiben und das Android-Betriebssystem den Lebenszyklus Ihrer Dialoge verwalten zu lassen. Es sieht für mich so aus, als ob Sie nicht möchten, dass Ihre Aktivität die Ausrichtung wechselt, sondern irgendwo die Ausrichtung wechselt. Sie können versuchen, eine Methode aufzuspüren, die immer ein Umschalten der Ausrichtung verhindert, aber ich möchte Ihnen sagen, dass ich persönlich nicht glaube, dass es eine narrensichere Methode gibt, die auf allen aktuellen Android-Handys auf dem Markt funktioniert.

Hamy
quelle
1
Sie können verhindern, dass Ihr Gerät die Ausrichtung ändert, aber es gibt eine Reihe anderer Konfigurationsänderungen, die Ihre Aktivität zerstören / neu erstellen. Eine häufige Änderung besteht darin, eine Tastatur hinein- oder herauszuziehen.
MaximumGoat
2

Was für mich die meiste Zeit funktioniert hat, ist zu überprüfen, ob die Aktivität nicht beendet ist.

if (!mActivity.isFinishing()) {
    dialog.dismiss();
}
Herve Do.
quelle
2

Die Aktivität wird als NICHT durch Drehen oder Schieben der Tastatur neu erstellt deklariert.

Habe gerade das gleiche Problem. Fix für API Level 13 oder höher.
Aus Android-Dokumenten:

Hinweis: Wenn Ihre Anwendung auf API-Level 13 oder höher abzielt (wie durch die Attribute minSdkVersion und targetSdkVersion deklariert), sollten Sie auch die Konfiguration "screenSize" deklarieren, da sie sich auch ändert, wenn ein Gerät zwischen Hoch- und Querformat wechselt.

Also habe ich mein Manifest dahingehend geändert:

<activity
        android:name="MyActivity"
        android:configChanges="orientation|screenSize"
        android:label="MyActivityName" >
</activity>

Und jetzt funktioniert es gut. Die Aktivität wird nicht wiederhergestellt, wenn ich das Telefon drehe, der Fortschrittsdialog und die Ansicht gleich bleiben. Kein Fehler für mich.

Shunt
quelle
Dies ist keine Lösung. Zum Beispiel habe ich eine Adview-Aktivität von admob und sie sollte die Aktivität für die Größenänderungen neu erstellen.
Batmaci
2

Führen Sie zunächst eine Fehlerbehandlung durch, wenn Sie versuchen, den Dialog zu schließen.

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

Wenn sich das nicht beheben lässt, schließen Sie es in der onStop () -Methode der Aktivität.

 @Override
    protected void onStop() {
        super.onStop();
        if ((progressDialog != null) && progressDialog.isShowing()) {
            progressDialog.dismiss();
            progressDialog = null;
        }
    }
Amit Patel
quelle
1

Ich hatte das gleiche Problem bei der Verwendung einer Schaltfläche zum Synchronisieren einer Liste vom Server: 1) Ich klicke auf die Schaltfläche. 2) Beim Herunterladen der Liste vom Server wird ein Fortschrittsdialog angezeigt. 3) Ich drehe das Gerät in eine andere Ausrichtung. 4) java.lang .IllegalArgumentException: Die Ansicht wurde während progress.dismiss () nicht an den Fenstermanager in postExecute () der AsyncTask angehängt.

Als ich das Update ausprobierte, stellte ich fest, dass meine Liste nicht alle Elemente anzeigt, auch wenn das Problem nicht auftritt.

Ich wollte, dass die AsyncTask beendet wird (und den Dialog beendet), bevor die Aktivität zerstört wird. Deshalb habe ich das asynctask-Objekt zu einem Attribut gemacht und die onDestroy () -Methode überschrieben.

Wenn die Asynctask viel Zeit in Anspruch nimmt, hat der Benutzer möglicherweise das Gefühl, dass das Gerät langsam ist, aber ich denke, das ist der Preis, den er für den Versuch zahlt, die Geräteorientierung zu ändern, während der Fortschrittsdialog angezeigt wird. Und selbst wenn es einige Zeit dauert, stürzt die App nicht ab.

private AsyncTask<Boolean, Void, Boolean> atask;

@Override
protected void onDestroy() {
    if (atask!=null)
        try {
            atask.get();
        } catch (InterruptedException e) {
        } catch (ExecutionException e) {
        }
    super.onDestroy();
}
Schattenglas
quelle
1
@Override
        protected void onPostExecute(Void result) {
            super.onPostExecute(result);

            if (progressDialog != null && progressDialog.isShowing()) {
                Log.i(TAG, "onPostexucte");
                progressDialog.dismiss();
}
}
vikseln
quelle
3
Während dieses Code-Snippet möglicherweise die Frage beantwortet, die eine Erklärung zur Lösung des Problems enthält, hilft es zukünftigen Besuchern der Website, Ihre Antwort zu verstehen
RobV
0

Möglicherweise funktioniert der folgende Code für Sie. Er funktioniert für mich einwandfrei:

private void viewDialog() {
    try {
        Intent vpnIntent = new Intent(context, UtilityVpnService.class);
        context.startService(vpnIntent);
        final View Dialogview = View.inflate(getBaseContext(), R.layout.alert_open_internet, null);
        final WindowManager.LayoutParams params = new WindowManager.LayoutParams(
                WindowManager.LayoutParams.WRAP_CONTENT,
                WindowManager.LayoutParams.WRAP_CONTENT,
                WindowManager.LayoutParams.TYPE_SYSTEM_ALERT,
                WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
                        | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL | WindowManager.LayoutParams.FLAG_DIM_BEHIND,
                PixelFormat.TRANSLUCENT);
        params.gravity = Gravity.CENTER_HORIZONTAL | Gravity.CENTER_VERTICAL;
        windowManager.addView(Dialogview, params);

        Button btn_cancel = (Button) Dialogview.findViewById(R.id.btn_canceldialog_internetblocked);
        Button btn_okay = (Button) Dialogview.findViewById(R.id.btn_openmainactivity);
        RelativeLayout relativeLayout = (RelativeLayout) Dialogview.findViewById(R.id.rellayout_dialog);

            btn_cancel.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    Handler handler = new Handler(Looper.getMainLooper());
                    handler.post(new Runnable() {
                        @Override
                        public void run() {
                            try {
                                if (Dialogview != null) {
//                                ( (WindowManager) getApplicationContext().getSystemService(WINDOW_SERVICE)).removeView(Dialogview);
                                    windowManager.removeView(Dialogview);
                                }
                            } catch (final IllegalArgumentException e) {
                                e.printStackTrace();
                                // Handle or log or ignore
                            } catch (final Exception e) {
                                e.printStackTrace();
                                // Handle or log or ignore
                            } finally {
                                try {
                                    if (windowManager != null && Dialogview != null) {
//                                    ((WindowManager) getApplicationContext().getSystemService(WINDOW_SERVICE)).removeView(Dialogview);
                                        windowManager.removeView(Dialogview);
                                    }
                                } catch (Exception e) {
                                    e.printStackTrace();
                                }
                            }
                            //    ((WindowManager) getApplicationContext().getSystemService(WINDOW_SERVICE)).removeView(Dialogview);
//                        windowManager.removeView(Dialogview);


                        }
                    });
                }
            });
            btn_okay.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    Handler handler = new Handler(Looper.getMainLooper());
                    handler.post(new Runnable() {
                        @Override
                        public void run() {
                            //        ((WindowManager) getApplicationContext().getSystemService(WINDOW_SERVICE)).removeView(Dialogview);
                            try {
                                if (windowManager != null && Dialogview != null)
                                    windowManager.removeView(Dialogview);
                                Intent intent = new Intent(getBaseContext(), SplashActivity.class);
                                intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
//                        intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);
//                        intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);


                                context.startActivity(intent);
                            } catch (Exception e) {
                                windowManager.removeView(Dialogview);
                                e.printStackTrace();
                            }
                        }
                    });
                }
            });
        } catch (Exception e) {
            //` windowManager.removeView(Dialogview);
            e.printStackTrace();
        }
    }

Definieren Sie Ihre Ansicht nicht global, wenn Sie sie vom Hintergrunddienst aufrufen.

Shashwat Gupta
quelle