Android: ProgressDialog.show () se bloquea con getApplicationContext

Parece que no puedo comprender por qué sucede esto. Este código:

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

funciona bien Sin embargo, este código:

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

arroja la siguiente excepción:

 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 

¿Alguna idea de por qué está pasando esto? onCreate esto desde el método onCreate .

¿Qué versión de API estás usando? Si estoy en lo cierto sobre cuál es el problema, esto se solucionó en Android 1.6 (API versión 4).

Parece que la referencia de objeto que getApplicationContext() devuelve solo apunta a nulo. Creo que estás teniendo un problema similar al que yo tuve porque parte del código en onCreate() se está ejecutando antes de que la ventana realmente se haya terminado de construir. Esto va a ser un truco, pero intenta lanzar un nuevo hilo en unos pocos cientos de milisegundos (IIRC: 300-400 parecía funcionar para mí, pero tendrás que retocar) que abre tu ProgressDialog y comienza cualquier cosa que necesites ( por ejemplo, red IO). Algo como esto:

 @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 } 

Estoy usando Android versión 2.1 con API Nivel 7. Enfrenté este problema (o similar) y lo resolví usando esto:

 Dialog dialog = new Dialog(this); 

en lugar de esto:

 Dialog dialog = new Dialog(getApplicationContext()); 

Espero que esto ayude 🙂

Para mí trabajó cambiando

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

a

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

Lo extraño es que el primero se puede encontrar en el tutorial de google y la gente obtiene un error en esto …

No creo que esto sea un problema de temporización en torno a un contexto de aplicación nulo

Intenta extender la Aplicación dentro de tu aplicación (o solo úsala si ya la tienes)

 public class MyApp extends Application 

Haga que la instancia esté disponible como un singleton privado. Esto nunca es nulo

 private static MyApp appInstance; 

Hacer un ayudante estático en MyApp (que usará el singleton)

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

¡¡AUGE!!

Además, consulte la respuesta del ingeniero de Android aquí: WindowManager $ BadTokenException

Una causa de este error puede ser intentar mostrar una ventana / diálogo de aplicación a través de un Contexto que no sea una Actividad.

Ahora, estoy de acuerdo, no tiene sentido que el método tome un parámetro de contexto, en lugar de actividad.

Después de leer las respuestas anteriores, encontré que para mi situación, lo siguiente solucionó el problema.

Esto arrojó el error

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

En base a las respuestas anteriores que sugerían que el contexto era el incorrecto, cambié el getApplicationContext () para recuperar el contexto de la vista pasada a los botones en el método Click.

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

No entiendo completamente el funcionamiento de Java, así que podría estar equivocado, pero supongo que para mi situación específica, la causa podría haber estado relacionada con el hecho de que el fragmento anterior se definió en una clase de Actividad abstracta; heredado y utilizado por muchas actividades, ¿quizás eso contribuyó al hecho de que getApplicationContext () no devuelva un contexto válido? (Solo una suposición).

Estoy creando una vista de mapa con superposiciones detalladas. Estaba creando mi itemizedoverlay como este desde mi mapActivity:

 OCItemizedOverlay currentLocationOverlay = new OCItemizedOverlay(pin,getApplicationContext); 

Descubrí que obtendría la excepción “android.view.WindowManager $ BadTokenException: no se puede agregar la ventana: nulo de token no es para una aplicación” cuando se activó el método onTap de my itemizedoverlay (cuando se toca la ubicación en la vista del mapa).

Descubrí que si simplemente pasaba ‘this’ en lugar de ‘getApplicationContext ()’ a mi constructor, el problema desaparecía. Esto parece apoyar la conclusión de alienjazzcat. extraño.

Para las actividades que se muestran en TabActivities use getParent ()

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

en lugar de

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

Para Android 2.2
Usa este código:

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

en lugar de este 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); 

Observación: Mi diálogo personalizado se crea fuera del método activity.onCreateDialog(int dialogId) .

Tratar –

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

Tuve un problema similar con los Fragmentos (de compatibilidad) en los que usar getActivity() dentro de ProgressDialog.show() bloquea. Estoy de acuerdo en que es por el tiempo.

Una posible solución:

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

En lugar de usar

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

Coloque el mContext lo antes posible para darle más tiempo para captar el contexto. Todavía no hay garantía de que esto funcione, solo reduce la probabilidad de un locking. Si todavía no funciona, tendrías que recurrir al hack de temporizador (que puede causar otros problemas de temporización como descartar el diálogo más adelante).

Por supuesto, si puede usar this o ActivityName.this , es más estable porque this ya apunta a algo. Pero en algunos casos, al igual que con ciertas architectures de Fragment, no es una opción.

(Para futuras referencias)

Creo que es porque hay diferencias en el contexto de la aplicación y el contexto de la actividad, como se explica aquí: http://www.doubleencore.com/2013/06/context/

Lo que significa que no podemos mostrar el diálogo utilizando el contexto de la aplicación. Eso es.

Para usar diálogos dentro de actividades, hazlo de esta manera:

 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 de fragmentos, hazlo de esta manera:

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

Eso es todo ^ _ ^

Lo que hice para evitar esto fue crear una clase base para todas mis actividades donde almaceno datos globales. En la primera actividad, guardé el contexto en una variable en mi clase base de esta manera:

Clase base

 public static Context myucontext; 

Primera actividad derivada de la clase base

 mycontext = this 

Luego utilizo mycontext en lugar de getApplicationContext al crear cuadros de diálogo.

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

Si está llamando a ProgressDialog.show () en un fragmento, convertir el mContext en Actividad me ha funcionado.

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

Implementé Alert Dialog para lanzar una excepción a la vista de actividades actual. Siempre que había dado así

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

Dada la misma excepción de ventana. Escribo el código de alerta de onCreate (). Tan simple que utilicé context = this; después de la setContentView() en el onCreate() Tantee la variable de contexto como global Context context;

Muestra de código es

 static Context context; public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.network); setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE); context = this; ....... 

Muestra de método de alerta es

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

Funciona bien para mí. En realidad, busqué este error en StackOverflow. Encontré esta consulta. Después de leer todas las respuestas de esta publicación, lo intenté de esta manera para que funcionara. Pensé que esta era una solución simple para superar la excepción.

Gracias, Rajendar

si tienes un problema con groupActivity no lo uses. PARENT es una estática del Parent ActivityGroup.

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

en lugar de

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

Un diálogo siempre se crea y se muestra como parte de una actividad. Debe pasar un contexto de actividad en lugar del contexto de la aplicación.

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

Este es un problema común. Use this lugar de getApplicationContext() Eso debería resolver su problema