Impossibile aggiungere la finestra: il token android.os.BinderProxy non è valido; la tua attività è in corso?


116

Provo a connettermi a Facebook tramite l'API di Facebook, seguo questo esempio: https://github.com/facebook/facebook-android-sdk/tree/master/examples/simple

Va tutto bene, ma quando provo a modificare un codice, voglio dire che voglio visualizzare il messaggio di dialogo post dopo che l'accesso è riuscito in questo modo:

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

Ricevo questo errore nel logcat:

03-02 13:32:08.629: E/AndroidRuntime(14991): android.view.WindowManager$BadTokenException: Unable to add window -- token android.os.BinderProxy@405180f8 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)

Qualche idea?



1
Controlla la risposta di seguito. Ho segnato che è corretto :)
Han Tran

Solo perché hai contrassegnato la risposta non cambia il fatto che si tratta di una domanda duplicata. L'altro è stato chiesto per primo ed è un problema identico con una risposta essenzialmente identica.
bsara

1
Hai visto che la mia domanda è di 2 anni fa?
Han Tran

1
Quindi sembra che gli altri moderatori abbiano un errore ma tu :)) Anw, grazie!
Han Tran

Risposte:


127

Ciò può verificarsi quando si mostra la finestra di dialogo per un contesto che non esiste più. Un caso comune: se l'operazione "mostra finestra di dialogo" è dopo un'operazione asincrona e durante tale operazione l'attività originale (che deve essere l'elemento padre della finestra di dialogo) viene distrutta. Per una buona descrizione, vedere questo post del blog e commenti:

http://dimitar.me/android-displaying-dialogs-from-background-threads/

Dall'analisi dello stack sopra, sembra che la libreria di Facebook esegua l'operazione di autenticazione in modo asincrono e si dispone di un meccanismo Handler - Callback (onComplete chiamato su un listener) che potrebbe facilmente creare questo scenario.

Quando l'ho visto riportato nella mia app, è piuttosto raro e corrisponde all'esperienza nel post del blog. Qualcosa è andato storto per l'attività / è stato distrutto durante il lavoro dell'AsyncTask. Non so come la tua modifica potrebbe risultare in questo ogni volta, ma forse stai facendo riferimento a un'attività come contesto per la finestra di dialogo che viene sempre distrutta dal momento in cui il tuo codice viene eseguito?

Inoltre, anche se non sono sicuro che questo sia il modo migliore per sapere se la tua attività è in corso, vedi questa risposta per un metodo per farlo:

Controlla se l'attività è attiva


3
Non chiamare dialog.show()risolve il problema, ma qual è il modo per essere in grado di mostrare ancora la mia finestra di dialogo?
natsumiyu

Per me, sto chiamando Fragment.getContext(), che funziona per API superiori a 21. Ma su Lollipop si arresta in modo
anomalo

158

Di tanto in tanto vedevo questo errore segnalato da alcune delle mie app ed ecco cosa lo ha risolto per me:

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

Tutte le altre risposte là fuori sembrano fare cose strane come scorrere l'elenco delle attività di corsa, ma questo è molto più semplice e sembra fare il trucco.


6
non risolve il problema, impedisce l'arresto anomalo e mostra anche la finestra di dialogo
YTerle

6
Ricorda solo che dovresti controllare context instanceof Activityo potresti ottenere un Exception!
FtheBuilder

3
oppure puoi usare getActivity (). isFinishing () invece del contesto
Nikita Axyonov

Sto usando API-23. Quando provo a usarlo nel mio MainActivity che estende AppCompatActivity. Mi mostra un errore come Caused by: java.lang.ClassCastException: com.creativeapp.hindihdvideosongs.AppController non può essere cast su android.app.Activity su com.creativeapp.hindihdvideosongs.MainActivity.onCreate (MainActivity.java:145) AppController è aggiunto nel mio AndroidMenifest
pavel

Non sto usando alcun dialogo e ricevo questo errore.
Abdul Waheed

10

una semplice soluzione è catturare l'eccezione:

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

Non è elegante ma a volte facile quando devi gestire le operazioni asincrone e non sei sicuro che l'attività sia attiva o meno quando vuoi mostrare la finestra di dialogo.


così brutto eppure così bello!
Rahul Tiwari

8
  • Nel mio caso il problema si è verificato a causa del tentativo di aprire / mostrare la finestra di dialogo in onPostExecuteAsyncTask

  • Tuttavia è un metodo sbagliato showing dialogo l'interfaccia utente cambia in onPostExecute.

  • Per questo, dobbiamo controllare che l'attività sia attiva Es .: !isFinishing() , se l'attività non è terminata, è possibile solo mostrare la nostra finestra di dialogo o la modifica dell'interfaccia utente.

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

1

Ho affrontato esattamente lo stesso problema. La chiamata ha '(!isFinishing())'impedito l'arresto anomalo, ma non è stato possibile visualizzare il messaggio di "avviso".

Quindi ho provato a rendere la funzione di chiamata "statica" , dove viene visualizzato l'avviso. Dopodiché, non si è verificato alcun arresto anomalo e viene visualizzato anche il messaggio.

Ad esempio:

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

Dopo aver eseguito il thread, aggiungi queste due righe di codice e questo risolverà il problema.

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

1

Un altro caso d'uso dello sviluppatore: se WindowManagero getWindow()viene chiamato su onCreate()o onStart()o onResume(), BadTokenExceptionviene generato un. Dovrai attendere che la vista sia preparata e allegata.

Spostare il codice per onAttachedToWindow()risolverlo. Potrebbe non essere una soluzione permanente, ma per quanto ho potuto testare, ha sempre funzionato.

Nel mio caso, c'era la necessità di aumentare la luminosità dello schermo quando l'attività diventava visibile. La riga getWindow().getAttributes().screenBrightnessnel ha onResume()provocato un'eccezione. Spostare il codice su ha onAttachedToWindow()funzionato.


0

Per me è stato risolto semplicemente rimuovendo la staticproprietà nei metodi DialogHelper.class (resposble per creare e nascondere la finestra di dialogo), poiché ho proprietà relative a Windowquei metodi


0

In dependencyServices nulla di quanto sopra mi ha aiutato, ho finito per fare come di seguito:

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

Devo usare la "doppia classe" perché un'interfaccia non può essere statica. L-


0

Impossibile aggiungere la finestra: il token non è valido; la tua attività è in corso?

Questo arresto anomalo è in genere causato dall'app che tenta di visualizzare una finestra di dialogo utilizzando un'attività terminata in precedenza come contesto. Ad esempio, ciò può accadere se un'attività attiva un AsyncTask che tenta di visualizzare una finestra di dialogo al termine, ma l'utente torna indietro dall'attività prima che l'attività sia completata.

Risorse esterne

Android - Visualizzazione delle finestre di dialogo dai thread in background

Errore: BinderProxy @ 45d459c0 non è valido; la tua attività è in corso?


0

L'ho risolto inserendo questo:

@Override
protected void onDestroy() {
    accessTokenTracker.stopTracking();
    super.onDestroy();
}

Per favore, scegli la lingua inglese quando pubblichi
Pedro Coelho
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.