Impossível adicionar janela - token android.os.BinderProxy não é válido; sua atividade está funcionando?

116

Tento me conectar ao Facebook através da API do Facebook, sigo este exemplo: https://github.com/facebook/facebook-android-sdk/tree/master/examples/simple

Tudo está bem, mas quando tento editar algum código, quero dizer que quero exibir a mensagem de caixa de diálogo após o login ser bem-sucedido, assim:

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

Recebo este erro no 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)

Qualquer ideia?

Han Tran
fonte
1
Verifique a resposta abaixo. Eu marquei que está correto :)
Han Tran
Só porque você marcou a resposta não altera o fato de que esta é uma pergunta duplicada. O outro foi perguntado primeiro e é um problema idêntico com uma resposta essencialmente idêntica.
bsara
1
Você viu que minha pergunta é há 2 anos?
Han Tran
1
Portanto, pareça com os outros O moderador errou, mas você :)) Ei, obrigado!
Han Tran

Respostas:

127

Isso pode ocorrer quando você está mostrando a caixa de diálogo para um contexto que não existe mais. Um caso comum - se a operação 'mostrar caixa de diálogo' ocorrer após uma operação assíncrona e, durante essa operação, a atividade original (ou seja, ser o pai de sua caixa de diálogo) é destruída. Para obter uma boa descrição, consulte esta postagem e comentários do blog:

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

A partir do rastreamento de pilha acima, parece que a biblioteca do Facebook gira a operação de autenticação de forma assíncrona e você tem um mecanismo Handler - Callback (onComplete chamado em um ouvinte) que poderia facilmente criar este cenário.

Quando vi isso relatado em meu aplicativo, é muito raro e corresponde à experiência na postagem do blog. Algo deu errado na atividade / foi destruída durante o trabalho da AsyncTask. Não sei como sua modificação pode resultar nisso todas as vezes, mas talvez você esteja se referindo a uma Activity como o contexto para a caixa de diálogo que sempre é destruída no momento em que seu código é executado?

Além disso, embora eu não tenha certeza se esta é a melhor maneira de saber se sua atividade está em execução, veja esta resposta para um método de fazer isso:

Verifique se a atividade está ativa

Peter Pascale
fonte
3
Não chamar dialog.show()resolve o problema, mas qual é a solução para que ainda possa mostrar meu diálogo?
natsumiyu
Para mim, estou chamando Fragment.getContext(), que funciona para APIs acima de 21. Mas no Lollipop ele trava
TheRealChx101
158

Eu estava vendo esse erro ser relatado de vez em quando em alguns dos meus aplicativos e aqui está o que o resolveu:

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

Todas as outras respostas por aí parecem estar fazendo coisas estranhas, como iterar através da lista de atividades em execução, mas isso é muito mais simples e parece funcionar.

DiscDev
fonte
6
não resolve o problema, evita travamento e também mostra diálogo
YTerle
6
Lembre-se de que você deve verificar context instanceof Activityou poderá obter um Exception!
FtheBuilder
3
ou você pode usar getActivity (). isFinishing () em vez de context
Nikita Axyonov
Estou usando a API-23. Quando tento usar isso na minha MainActivity, que estende AppCompatActivity. Isso me mostra um erro como Causado por: java.lang.ClassCastException: com.creativeapp.hindihdvideosongs.AppController não pode ser transmitido para android.app.Activity em com.creativeapp.hindihdvideosongs.MainActivity.onCreate (MainActivity.java:145) AppController é adicionado ao meu AndroidMenifest
pavel
Não estou usando nenhum diálogo e recebendo este erro.
Abdul Waheed
11

uma solução simples é capturar a exceção:

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

Não é elegante, mas às vezes é fácil quando você precisa gerenciar operações assíncronas e não tem certeza se a atividade está ativa ou não quando deseja mostrar a caixa de diálogo.

gerz
fonte
1
tão feio mas tão bonito!
Rahul Tiwari
8
  • No meu caso, o problema ocorreu porque estou tentando abrir / mostrar a caixa de diálogo em onPostExecuteAsyncTask

  • No entanto, é um método errado de showing dialogou mudanças de interface do usuário onPostExecute.

  • Para isso, é necessário verificar se a atividade está ativa. Ex .: !isFinishing() , se a atividade não for finalizada só poderemos mostrar nossa caixa de diálogo ou alteração da interface do usuário.

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

Eu enfrentei exatamente o mesmo problema. Chamar '(!isFinishing())'evitou o travamento, mas não pôde exibir a mensagem de 'alerta'.

Em seguida, tentei tornar a função de chamada 'estática' , onde o alerta é exibido. Depois disso, nenhuma falha aconteceu e a mensagem também foi exibida.

Por 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();      
    }
ArunJTS
fonte
1

Depois de executar o thread, adicione essas duas linhas de código e isso resolverá o problema.

Looper.loop();
Looper.myLooper().quit();
Balachandran Muthuraj
fonte
1

Outro caso de uso de desenvolvedor: se WindowManagerou getWindow()estiver sendo chamado em onCreate()ou onStart()ou onResume(), a BadTokenExceptionserá lançado. Você precisará esperar até que a vista seja preparada e anexada.

Mover o código para onAttachedToWindow()resolvê-lo. Pode não ser uma solução permanente, mas por mais que pude testar, sempre funcionou.

No meu caso, houve a necessidade de aumentar o brilho da tela quando a atividade se tornou visível. A linha getWindow().getAttributes().screenBrightnessno onResume()resultou em uma exceção. Mover o código onAttachedToWindow()funcionou.

Ram Iyer
fonte
0

Para mim, isso foi corrigido apenas removendo a staticpropriedade nos métodos DialogHelper.class (responsável por criar e ocultar a caixa de diálogo), pois tenho propriedades relacionadas a Windowesses métodos

Dasser Basyouni
fonte
0

Em dependencyServices nada do acima me ajudou, acabei fazendo o seguinte:

    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 usar a "classe dupla" porque uma interface não pode ser estática. EU-

Legião
fonte
0

Incapaz de adicionar janela - o token não é válido; sua atividade está funcionando?

Essa falha geralmente é causada por seu aplicativo tentando exibir uma caixa de diálogo usando uma atividade concluída anteriormente como contexto. Por exemplo, isso pode acontecer se uma Activity disparar uma AsyncTask que tenta exibir uma caixa de diálogo quando é concluída, mas o usuário navega de volta da Activity antes que a tarefa seja concluída.

Fontes externas

Android - Exibindo Diálogos de Tópicos de Fundo

Erro: BinderProxy @ 45d459c0 não é válido; sua atividade está funcionando?

Bholendra Singh
fonte
0

Eu resolvi colocando o seguinte:

@Override
protected void onDestroy() {
    accessTokenTracker.stopTracking();
    super.onDestroy();
}
Juan L. Antón Santamaria
fonte
Por favor, escolha o idioma inglês ao postar
Pedro Coelho