wake-up-neo.com

Fenster - Token Android.os.BinderProxy kann nicht hinzugefügt werden. läuft Ihre Aktivität?

Ich versuche, über Facebook API eine Verbindung zu Facebook herzustellen. Ich folge diesem Beispiel: https://github.com/facebook/facebook-Android-sdk/tree/master/examples/simple

Alles ist in Ordnung, aber wenn ich versuche, etwas Code zu bearbeiten, möchte ich die Dialognachricht anzeigen, nachdem der Login erfolgreich war:

public void onAuthSucceed() {
        mText.setText("You have logged in! ");   
        //This is the code to call the post message dialog.                     
        mFacebook.dialog(Example.this, "feed",new SampleDialogListener());   
    }

Ich erhalte diesen Fehler im Logcat:

03-02 13:32:08.629: E/AndroidRuntime(14991): Android.view.WindowManager$BadTokenException: Unable to add window -- token [email protected] is not valid; is your activity running?
03-02 13:32:08.629: E/AndroidRuntime(14991):    at Android.view.ViewRoot.setView(ViewRoot.Java:532)
03-02 13:32:08.629: E/AndroidRuntime(14991):    at Android.view.WindowManagerImpl.addView(WindowManagerImpl.Java:177)
03-02 13:32:08.629: E/AndroidRuntime(14991):    at Android.view.WindowManagerImpl.addView(WindowManagerImpl.Java:91)
03-02 13:32:08.629: E/AndroidRuntime(14991):    at Android.view.Window$LocalWindowManager.addView(Window.Java:424)
03-02 13:32:08.629: E/AndroidRuntime(14991):    at Android.app.Dialog.show(Dialog.Java:241)
03-02 13:32:08.629: E/AndroidRuntime(14991):    at com.facebook.Android.Facebook.dialog(Facebook.Java:780)
03-02 13:32:08.629: E/AndroidRuntime(14991):    at com.facebook.Android.Facebook.dialog(Facebook.Java:737)
03-02 13:32:08.629: E/AndroidRuntime(14991):    at com.facebook.Android.Example$SampleAuthListener.onAuthSucceed(Example.Java:113)
03-02 13:32:08.629: E/AndroidRuntime(14991):    at com.facebook.Android.SessionEvents.onLoginSuccess(SessionEvents.Java:78)
03-02 13:32:08.629: E/AndroidRuntime(14991):    at com.facebook.Android.Example$LoginDialogListener.onComplete(Example.Java:88)
03-02 13:32:08.629: E/AndroidRuntime(14991):    at com.facebook.Android.Facebook$1.onComplete(Facebook.Java:320)
03-02 13:32:08.629: E/AndroidRuntime(14991):    at com.facebook.Android.FbDialog$FbWebViewClient.shouldOverrideUrlLoading(FbDialog.Java:144)
03-02 13:32:08.629: E/AndroidRuntime(14991):    at Android.webkit.CallbackProxy.uiOverrideUrlLoading(CallbackProxy.Java:218)
03-02 13:32:08.629: E/AndroidRuntime(14991):    at Android.webkit.CallbackProxy.handleMessage(CallbackProxy.Java:337)
03-02 13:32:08.629: E/AndroidRuntime(14991):    at Android.os.Handler.dispatchMessage(Handler.Java:99)
03-02 13:32:08.629: E/AndroidRuntime(14991):    at Android.os.Looper.loop(Looper.Java:130)
03-02 13:32:08.629: E/AndroidRuntime(14991):    at Android.app.ActivityThread.main(ActivityThread.Java:3687)
03-02 13:32:08.629: E/AndroidRuntime(14991):    at Java.lang.reflect.Method.invokeNative(Native Method)
03-02 13:32:08.629: E/AndroidRuntime(14991):    at Java.lang.reflect.Method.invoke(Method.Java:507)
03-02 13:32:08.629: E/AndroidRuntime(14991):    at com.Android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.Java:867)
03-02 13:32:08.629: E/AndroidRuntime(14991):    at com.Android.internal.os.ZygoteInit.main(ZygoteInit.Java:625)
03-02 13:32:08.629: E/AndroidRuntime(14991):    at dalvik.system.NativeStart.main(Native Method)

Irgendeine Idee? 

84
Han Tran

Dies kann vorkommen, wenn Sie den Dialog für einen Kontext anzeigen, der nicht mehr vorhanden ist. Ein häufiger Fall - wenn der Vorgang 'Dialog anzeigen' nach einem asynchronen Vorgang erfolgt, wird die ursprüngliche Aktivität (dh die übergeordnete Aktivität Ihres Dialogs) zerstört. Eine gute Beschreibung finden Sie in diesem Blogbeitrag und in den Kommentaren:

http://dimitar.me/Android-displaying-dialogs-von-background-threads/

Aus der Stack-Ablaufverfolgung oben scheint es, dass die Facebook-Bibliothek den Auth-Vorgang asynchron ausdreht, und Sie haben einen Handler-Callback-Mechanismus (onComplete, der von einem Listener aufgerufen wird), mit dem dieses Szenario leicht erstellt werden kann.

Wenn ich das in meiner App berichtet habe, ist es ziemlich selten und stimmt mit der Erfahrung im Blog-Post überein. Bei der Aktivität ist ein Fehler aufgetreten/sie wurde während der Arbeit der AsyncTask zerstört. Ich weiß nicht, wie Ihre Änderung dies jedes Mal zur Folge haben könnte, aber vielleicht beziehen Sie sich auf eine Aktivität als Kontext für den Dialog, der immer zerstört wird, wenn Ihr Code ausgeführt wird.

Auch wenn ich nicht sicher bin, ob dies der beste Weg ist, um festzustellen, ob Ihre Aktivität ausgeführt wird, finden Sie in dieser Antwort eine Methode:

Überprüfen Sie, ob die Aktivität aktiv ist

101
Peter Pascale

Ich habe gesehen, dass dieser Fehler gelegentlich von einigen meiner Apps gemeldet wurde. Hier ist, was er für mich gelöst hat:

if(!((Activity) context).isFinishing())
{
    //show dialog
}

Alle anderen Antworten da draußen scheinen seltsame Dinge zu tun, wie das Durchlaufen der Liste der laufenden Aktivitäten. Dies ist jedoch viel einfacher und scheint den Trick zu erfüllen.

122
DiscDev

eine einfache Problemumgehung besteht darin, die Ausnahme abzufangen: 

try {
        alertDialog.show()
    }
catch (WindowManager.BadTokenException e) {
        //use a log message
    }

Es ist nicht elegant, aber manchmal einfach, wenn Sie asynchrone Vorgänge verwalten müssen und nicht wissen, ob die Aktivität aktiv ist oder nicht, wenn Sie das Dialogfeld anzeigen möchten.

4
gerz

Diese Website listet 3 verschiedene Methoden auf, um zu überprüfen, ob ein bestimmtes Activity ausgeführt wird , und stellt Code-Snippets zur Verfügung, um Ihnen zu helfen . Beachten Sie jedoch, dass die Überprüfung, ob eine Aktivität noch ausgeführt wird , nur zu Debugging-Zwecken empfohlen wird, da das Ergebnis alles andere als sicher und daher nicht geeignet ist Code/Logikfluss.

3
ACLima

Fügen Sie nach der Ausführung des Threads diese beiden Codezeilen hinzu, um das Problem zu lösen.

Looper.loop();
Looper.myLooper().quit();

Ich hatte genau das gleiche Problem. Durch das Aufrufen von '(!isFinishing())' wurde der Absturz verhindert, jedoch konnte die Warnmeldung nicht angezeigt werden.

Dann habe ich versucht, die aufrufende Funktion 'static' zu erstellen, wobei die Warnung angezeigt wird. Danach ist kein Absturz aufgetreten und die Meldung wird ebenfalls angezeigt.

Für ex:

public static void connect_failure() {      
        Log.i(FW_UPD_APP, "Connect failed");

        new AlertDialog.Builder(MyActivity)
        .setTitle("Title")
        .setMessage("Message")
        .setPositiveButton(Android.R.string.yes, new DialogInterface.OnClickListener() {
            public void onClick(DialogInterface dialog, int which) { 
                  //do nothing
            }
         })
        .setIcon(R.drawable.the_image).show();      
    }
1
ArunJTS

Für mich wurde das Problem behoben, indem einfach die static -Eigenschaft in den DialogHelper.class-Methoden entfernt wurde (Verantwortlicher für das Erstellen und Ausblenden des Dialogs), da ich Eigenschaften habe, die mit Window in diesen Methoden zusammenhängen

0
Dasser Basyouni
  • In meinem Fall ist das Problem aufgetreten, weil versucht wurde, das Dialogfeld in onPostExecute AsyncTask zu öffnen/anzuzeigen

  • Es ist jedoch eine falsche Methode von showing dialog oder Ui in onPostExecute.

  • Dazu müssen wir überprüfen, ob die Aktivität aktiv ist zB: !isFinishing(), wenn die Aktivität nicht beendet ist, können nur unser Dialogfeld oder die UI-Änderung angezeigt werden. 

    @Override
    protected void onPostExecute(String response_str) {
    
       getActivity().runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        if (!((Activity) mContext).isFinishing()) {
                            try {
                                ShowAgilDialog();
                            } catch (WindowManager.BadTokenException e) {
                                Log.e("WindowManagerBad ", e.toString());
                            }
                        }
                    }
                });
    }
    
0
Agilanbu

Unter dependencyServices hat mir nichts von dem oben Genannten geholfen. Am Ende habe ich Folgendes getan:

    class Static_Toast_Android
    {
        private static Context _context
        {
            get { return Android.App.Application.Context; }
        }
        public static void StaticDisplayToast(string message)
        {
            Toast.MakeText(_context, message, ToastLength.Long).Show();
        }
    }
    public class Toast_Android : IToast
    {

        public void DisplayToast(string message)
        {
            Static_Toast_Android.StaticDisplayToast(message);
        }
    }

Ich muss die "Doppelklasse" verwenden, da eine Schnittstelle nicht statisch sein kann. L-

0
Legion