Pergunta

Não consigo entender por que isso está acontecendo. Este código:

mProgressDialog = ProgressDialog.show(this, "", getString(R.string.loading), true);

Funciona muito bem. No entanto, este código:

mProgressDialog = ProgressDialog.show(getApplicationContext(), "", getString(R.string.loading), true);

joga a seguinte exceção:

W/WindowManager(  569): Attempted to add window with non-application token WindowToken{438bee58 token=null}.  Aborting.
D/AndroidRuntime( 2049): Shutting down VM
W/dalvikvm( 2049): threadid=3: thread exiting with uncaught exception (group=0x4001aa28)
E/AndroidRuntime( 2049): Uncaught handler: thread main exiting due to uncaught exception
E/AndroidRuntime( 2049): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.tastekid.TasteKid/com.tastekid.TasteKid.YouTube}: android.view.WindowManager$BadTokenException: Unable to add window -- token null is not for an application
E/AndroidRuntime( 2049):    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2401)
E/AndroidRuntime( 2049):    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2417)
E/AndroidRuntime( 2049):    at android.app.ActivityThread.access$2100(ActivityThread.java:116)
E/AndroidRuntime( 2049):    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1794)
E/AndroidRuntime( 2049):    at android.os.Handler.dispatchMessage(Handler.java:99)
E/AndroidRuntime( 2049):    at android.os.Looper.loop(Looper.java:123)
E/AndroidRuntime( 2049):    at android.app.ActivityThread.main(ActivityThread.java:4203)
E/AndroidRuntime( 2049):    at java.lang.reflect.Method.invokeNative(Native Method)
E/AndroidRuntime( 2049):    at java.lang.reflect.Method.invoke(Method.java:521)
E/AndroidRuntime( 2049):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:791)
E/AndroidRuntime( 2049):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:549)
E/AndroidRuntime( 2049):    at dalvik.system.NativeStart.main(Native Method)
E/AndroidRuntime( 2049): Caused by: android.view.WindowManager$BadTokenException: Unable to add window -- token null is not for an application
E/AndroidRuntime( 2049):    at android.view.ViewRoot.setView(ViewRoot.java:460)
E/AndroidRuntime( 2049):    at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:177)
E/AndroidRuntime( 2049):    at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:91)
E/AndroidRuntime( 2049):    at android.app.Dialog.show(Dialog.java:238)
E/AndroidRuntime( 2049):    at android.app.ProgressDialog.show(ProgressDialog.java:107)
E/AndroidRuntime( 2049):    at android.app.ProgressDialog.show(ProgressDialog.java:90)
E/AndroidRuntime( 2049):    at com.tastekid.TasteKid.YouTube.onCreate(YouTube.java:45)
E/AndroidRuntime( 2049):    at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1123)
E/AndroidRuntime( 2049):    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2364)
E/AndroidRuntime( 2049):    ... 11 more

Alguma idéia de por que isso está acontecendo? Estou chamando isso do onCreate método.

Foi útil?

Solução

Qual versão da API você está usando? Se estou certo sobre qual é o problema, isso foi corrigido no Android 1.6 (API Version 4).

Parece que a referência de objeto que getApplicationContext() está retornando apenas aponta para NULL. Eu acho que você está tendo um problema semelhante ao que eu tive, em que parte do código no onCreate() está sendo executado antes que a janela seja feita sendo construída. Isso vai ser um hack, mas tente lançar um novo tópico em algumas centenas de milissegundos (IIRC: 300-400 parecia funcionar para mim, mas você precisará mexer) que abre seu progresso e inicia qualquer outra coisa que você precisasse ( por exemplo, rede io). Algo assim:

@Override
public void onCreate(Bundle savedInstanceState) {
    // do all your other stuff here

    new Handler().postDelayed(new Runnable() {
        @Override
        public void run() {
            mProgressDialog = ProgressDialog.show(
               YouTube.this.getApplicationContext(), "",
               YouTube.this.getString(R.string.loading), true);

            // start time consuming background process here
        }
    }, 1000); // starting it in 1 second
}

Outras dicas

Estou usando o Android versão 2.1 com o nível da API 7. Confronho com esse problema (ou similar) e resolvido usando isso:

Dialog dialog = new Dialog(this);

em vez disso:

Dialog dialog = new Dialog(getApplicationContext());

Espero que isto ajude :)

Para mim, trabalhou mudando

builder = new AlertDialog.Builder(getApplicationContext());

para

builder = new AlertDialog.Builder(ThisActivityClassName.this);

A coisa estranha é que o primeiro pode ser encontrado no tutorial do Google e as pessoas recebem erro nisso ..

Eu não acho que este é um problema de tempo em torno de um contexto de aplicativo nulo

Tente estender o aplicativo dentro do seu aplicativo (ou apenas use -o, se você já tiver)

public class MyApp extends Application

Disponibilize a instância como um singleton particular. Isto é nunca nulo

private static MyApp appInstance;

Faça um ajudante estático em MyApp (que usará o Singleton)

    public static void showProgressDialog( CharSequence title, CharSequence message )
{
    prog = ProgressDialog.show(appInstance, title, message, true); // Never Do This!
}

ESTRONDO!!

Além disso, confira a resposta do engenheiro do Android aqui: WindowManager $ badTokeNexception

Uma causa desse erro pode estar tentando exibir uma janela/diálogo do aplicativo através de um contexto que não é uma atividade.

Agora, eu concordo, não faz sentido que o método pegue um parâmetro de contexto, em vez de atividade ..

Depois de ler as respostas acima, descobri que, para minha situação, o seguinte corrigiu o problema.

Isso lançou o erro

myButton.setOnClickListener(new OnClickListener(){
    public void onClick(View v) {
        MyDialogue dialog = new MyDialogue(getApplicationContext());
        dialog.show();              
    }
});

Com base nas respostas anteriores que sugeriram que o contexto estava errado, mudei o getApplicationContext () para recuperar o contexto da exibição passada para os botões OnClick Method.

myButton.setOnClickListener(new OnClickListener(){
    public void onClick(View v) {
        MyDialogue dialog = new MyDialogue(v.getContext());
        dialog.show();              
    }
});

Não entendo completamente o funcionamento do Java para que eu possa estar errado, mas acho que, para minha situação específica, a causa poderia estar relacionada ao fato de que o trecho acima foi definido em uma classe de atividade abstrata; herdado e usado por muitas atividades, talvez isso contribuiu para o fato de que getApplicationContext () não retorna um contexto válido? (Apenas um palpite).

Estou criando uma exibição de mapa com sobreposições detalhadas. Eu estava criando meu detalhe sobrevivente como este da minha MapActivity:

OCItemizedOverlay currentLocationOverlay = new OCItemizedOverlay(pin,getApplicationContext);

Descobri que obteria o "Android.View.WindowManager $ BadTokenexception: Incapaz de adicionar janela - o token null não é para um aplicativo" Exceção quando o método ONTAP do meu itemizedOverlay foi acionado (quando o local é aproveitado no MapView).

Descobri que, se simplesmente passei, 'isso' em vez de 'getApplicationContext ()' para o meu construtor, o problema desapareceu. Isso parece apoiar a conclusão de AlienJazzcat. estranhas.

Para atividades mostradas dentro do uso de tabacidades getParent ()

final AlertDialog.Builder builder = new AlertDialog.Builder(getParent());

ao invés de

final AlertDialog.Builder builder = new AlertDialog.Builder(this);

Para Android 2.2
Use este código:

//activity is an instance of a class which extends android.app.Activity
Dialog dialog = new Dialog(activity);

Em vez deste código:

// this code produces an ERROR:
//android.view.WindowManager$BadTokenException: 
//Unable to add window -- token null is not for an application
Context mContext = activity.getApplicationContext();
Dialog dialog = new Dialog(mContext);

Observação: minha caixa de diálogo personalizada é criada fora activity.onCreateDialog(int dialogId) método.

Tentar -

AlertDialog.Builder builder = new AlertDialog.Builder(getParent());

Teve um problema semelhante com fragmentos (compatibilidade) nos quais usando um getActivity() dentro de ProgressDialog.show() trava. Eu concordo que é por causa do tempo.

Uma possível correção:

mContext = getApplicationContext();

if (mContext != null) {
    mProgressDialog = ProgressDialog.show(mContext, "", getString(R.string.loading), true);
}

ao invés de usar

mProgressDialog = ProgressDialog.show(getApplicationContext(), "", getString(R.string.loading), true);

Coloque o McOntext o mais cedo possível para dar mais tempo para pegar o contexto. Ainda não há garantia de que isso funcione, apenas reduz a probabilidade de um acidente. Se ainda não funcionar, você teria que recorrer ao hacker do timer (o que pode causar outros problemas de tempo, como descartar a caixa de diálogo mais tarde).

Claro, se você pode usar this ou ActivityName.this, é mais estável porque this já aponta para algo. Mas, em alguns casos, como em certas arquiteturas de fragmentos, não é uma opção.

(Para referências futuras)

Eu acho que é porque há diferenças no contexto do aplicativo e no contexto da atividade, conforme explicado aqui: http://www.doubleencore.com/2013/06/context/

O que significa que não podemos mostrar a caixa de diálogo usando o contexto do aplicativo. É isso.

Para usar diálogos dentro das atividades, faça -o da seguinte:

private Context mContext;
private AlertDialog.Builder mBuilder;

@Override
protected void onCreate(Bundle savedInstanceState) {
     super.onCreate(savedInstanceState);
     mContext = this;

     //using mContext here refering to activity context
     mBuilder = new AlertDialog.Builder(mContext);
     //...
     //rest of the code
     //...
}

Para usar diálogos dentro dos fragmentos, faça -o da seguinte:

private Context mContext;
private AlertDialog.Builder mBuilder;

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
      View mRootView = inflater.inflate(R.layout.fragment_layout, container, false);
      mContext = getActivity();

      //using mContext here refering to fragment's hosting activity context
      mBuilder = new AlertDialog.Builder(mContext);
      //...
      //rest of the code
      //...
      return mRootView;
}

É isso ^_ ^

O que eu fiz para contornar isso foi criar uma classe base para todas as minhas atividades em que eu guardo dados globais. Na primeira atividade, salvei o contexto em uma variável na minha classe base como:

Classe base

public static Context myucontext; 

Primeira atividade derivada da classe base

mycontext = this

Então eu uso o MyContext em vez do getApplicationContext ao criar diálogos.

AlertDialog alertDialog = new AlertDialog.Builder(mycontext).create();

Se você está chamando o ProgressDialog.Show () em um fragmento, lançando o McOntext para a atividade funcionou para mim.

     ProgressDialog pd = new ProgressDialog((Activity) mContext);

Eu implementei o diálogo de alerta para exceção que se dedica à visão atual da Actititty. Sempre que eu havia dado assim

AlertDialog.Builder builder = new AlertDialog.Builder(context);

Dada a mesma exceção da janela. context = this; depois setContentView() declaração em onCreate() Method.teu a variável de contexto como global como Context context;

O exemplo de código é

static Context context;

 public void onCreate(Bundle savedInstanceState)  { 
        super.onCreate(savedInstanceState); 


        setContentView(R.layout.network); 
        setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);

        context = this;
.......

A amostra do método de alerta é

private void alertException(String execMsg){
        Log.i(TAG,"in alertException()..."+context);
        Log.e(TAG,"Exception :"+execMsg);
        AlertDialog.Builder builder = new AlertDialog.Builder(context);
.......

Funciona bem para mim. Na verdade, procurei esse erro no StackOverflow, encontrei esta consulta. Depois de ler todas as respostas desta postagem, tentei dessa maneira para que funcione. Eu pensei que essa é uma solução simples para superar a exceção.

Obrigado, Rajendar

Se você tiver um problema no grupo, não use isso. O pai é um estático do grupo de atividades pai.

final AlertDialog.Builder builder = new AlertDialog.Builder(GroupActivityParent.PARENT);

ao invés de

final AlertDialog.Builder builder = new AlertDialog.Builder(getParent());

Uma caixa de diálogo é sempre criada e exibida como parte de uma atividade. Você precisa passar em um contexto de atividade em vez do contexto do aplicativo.

http://developer.android.com/guide/topics/ui/dialogs.html#showingadialog

Esse é um problema comum. Usar this ao invés de getApplicationContext()Isso deve resolver seu problema

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top