progressbar - Android: ProgressDialog.show() se bloquea con getApplicationContext
progressdialog android asynctask (17)
¿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
}
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
.
(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.
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.
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 :)
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 . 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
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();
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.
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)
.
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 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 ...
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 ^ _ ^
Si está llamando a ProgressDialog.show () en un fragmento, convertir el mContext en Actividad me ha funcionado.
ProgressDialog pd = new ProgressDialog((Activity) mContext);
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 bloqueo. 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 arquitecturas de Fragment, no es una opción.
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
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());