108 votes

Android : ProgressDialog.show() se plante avec getApplicationContext

Je n'arrive pas à comprendre pourquoi cela se produit. Ce code :

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

fonctionne très bien. Cependant, ce code :

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

lance l'exception suivante :

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

Une idée de la raison pour laquelle cela se produit ? J'appelle cette fonction à partir du onCreate méthode.

127voto

Taner Points 2442

J'utilise la version 2.1 d'Android avec le niveau 7 de l'API. J'ai été confronté à ce problème (ou un problème similaire) et je l'ai résolu en utilisant ceci :

Dialog dialog = new Dialog(this);

au lieu de ça :

Dialog dialog = new Dialog(getApplicationContext());

J'espère que cela vous aidera :)

64voto

wtk Points 633

Pour moi, cela a marché de changer

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

a

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

La chose étrange est que le premier peut être trouvé dans le tutoriel de google et les gens obtiennent l'erreur sur ce

42voto

fiXedd Points 21644

Quelle version de l'API utilisez-vous ? Si je ne me trompe pas, le problème a été corrigé dans Android 1.6 (version 4 de l'API).

Il semble que la référence de l'objet que getApplicationContext() ne renvoie que des points à null. Je pense que vous avez un problème similaire à celui que j'ai eu, dans la mesure où une partie du code de l'application onCreate() est exécuté avant la fin de la construction de la fenêtre. Cela va être un hack, mais essayez de lancer un nouveau Thread dans quelques centaines de millisecondes (IIRC : 300-400 semblait fonctionner pour moi, mais vous aurez besoin de bricoler) qui ouvre votre ProgressDialog et lance tout ce dont vous avez besoin (par exemple, IO réseau). Quelque chose comme ceci :

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

23voto

alienjazzcat Points 727

Je ne pense pas qu'il s'agisse d'un problème de timing autour d'un contexte d'application nul.

Essayez d'étendre l'application dans votre application (ou utilisez-la si vous l'avez déjà fait).

public class MyApp extends Application

Rend l'instance disponible en tant que singleton privé. Ceci est jamais nul

private static MyApp appInstance;

Créez une aide statique dans MyApp (qui utilisera le singleton).

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

BOOM !

Vous pouvez également consulter la réponse de l'ingénieur Android ici : WindowManager$BadTokenException

L'une des causes de cette erreur peut être d'essayer d'afficher une fenêtre/un dialogue d'application par le biais d'un fichier C. d'une application par le biais d'un contexte qui n'est pas une activité.

Maintenant, je suis d'accord, cela n'a pas de sens que la méthode prenne un paramètre Contexte, au lieu de Activity

10voto

Emile Points 4660

Après avoir lu les réponses ci-dessus, j'ai trouvé que, dans ma situation, ce qui suit a réglé le problème.

L'erreur suivante s'est produite

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

Sur la base des réponses précédentes qui suggéraient que le contexte n'était pas le bon, j'ai modifié la méthode getApplicationContext() pour récupérer le contexte de la vue passée à la méthode onClick des boutons.

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

Je ne comprends pas totalement le fonctionnement de Java, je peux donc me tromper, mais je suppose que dans mon cas particulier, la cause pourrait être liée au fait que l'extrait ci-dessus a été défini dans une classe d'activité abstraite, héritée et utilisée par de nombreuses activités, ce qui a peut-être contribué au fait que getApplicationContext() ne renvoie pas un contexte valide ? (Juste une supposition).

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X