Question

Je ne peux pas sembler comprendre pourquoi ce qui se passe. 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);

lève 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

Toutes les idées pourquoi cela se passe? J'appelle ce par la méthode de onCreate.

Était-ce utile?

La solution

Quelle version API utilisez-vous? Si je ne me trompe pas sur ce que le problème est alors cela a été corrigé dans Android 1.6 (version API 4).

Il ressemble à la référence d'objet qui getApplicationContext() revient juste des points à null. Je pense que vous rencontrez un problème similaire à celui que j'avais dans cette partie du code dans le onCreate() est en cours exécutée avant la fenêtre se fait réellement en cours de construction. Cela va être un hack, mais essayez de lancer une nouvelle discussion en quelques centaines de millisecondes (IIRC: 300-400 semblait fonctionner pour moi, mais vous aurez besoin de bricoler) qui ouvre votre ProgressDialog et commence tout ce que vous aviez besoin ( ex. réseau IO). 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
}

Autres conseils

J'utilise la version Android 2.1 avec l'API de niveau 7. Je face à ce problème (ou similaire) et résolu en utilisant ceci:

Dialog dialog = new Dialog(this);

au lieu de ceci:

Dialog dialog = new Dialog(getApplicationContext());

Hope this helps:)

Pour me traitèrent changer

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

à

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

chose étrange est que le premier peut être trouvé dans le tutoriel Google et les gens se erreur sur cette ..

Je ne pense pas que ce soit un problème de synchronisation dans un contexte d'application nulle

Essayez étendre l'application au sein de votre application (ou simplement l'utiliser si vous avez déjà)

public class MyApp extends Application

Faire l'instance disponible en tant que singleton privé. Ceci est jamais null

private static MyApp appInstance;

Faire 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 !!

En outre, consultez la réponse de l'ingénieur Android ici: WindowManager $ BadTokenException

  

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

Maintenant, je suis d'accord, il n'a pas de sens que la méthode prend un contexte param, au lieu de l'activité ..

Après avoir lu les réponses ci-dessus je trouve que pour ma situation ce qui suit résolu le problème.

a jeté l'erreur

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 le contexte était le mauvais, j'ai changé le getApplicationContext () pour récupérer le contexte de la vue adoptée en aux touches méthode onClick.

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

Je ne comprends pas bien le fonctionnement de Java pour que je puisse me tromper, mais je devine que ma situation particulière la cause aurait pu être lié au fait que l'extrait ci-dessus a été définie dans une classe abstraite d'activité; hérité et utilisé par de nombreuses activités, peut-être contribué au fait que getApplicationContext () ne renvoie pas un contexte valide ?? (Juste une supposition).

Je suis en train de créer une vue sur la carte avec des superpositions détaillées. Je créais mon itemizedoverlay comme ça de mon mapActivity:

OCItemizedOverlay currentLocationOverlay = new OCItemizedOverlay(pin,getApplicationContext);

Je trouve que je recevrais la « android.view.WindowManager $ BadTokenException: Impossible d'ajouter la fenêtre - null jeton n'est pas pour une application » exception lorsque ma méthode de itemizedoverlay onTap a été déclenchée (lorsque l'emplacement est exploité sur le MapView ).

Je trouve que si je passais simplement, « ceci » au lieu de « getApplicationContext () » à mon constructeur, le problème a disparu. Cela semble appuyer la conclusion de alienjazzcat. bizarre.

Pour les activités présentées dans les TabActivities utilisent getParent ()

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

au lieu de

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

Pour Android 2.2
Utilisez ce code:

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

à la place de ce code:

// 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);

Remarque:. Ma boîte de dialogue personnalisée est créée en dehors de la méthode activity.onCreateDialog(int dialogId)

Essayez -

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

eu un problème similaire avec (compatibilité) Fragments dans lequel en utilisant un getActivity() à l'intérieur de plante ProgressDialog.show() il. Je suis d'accord qu'il est en raison du moment.

Une solution possible:

mContext = getApplicationContext();

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

au lieu d'utiliser

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

Placez le mContext le plus tôt possible pour lui donner plus de temps pour saisir le contexte. Il n'y a toujours pas de garantie que cela fonctionne, il réduit simplement la probabilité d'un accident. Si cela ne fonctionne toujours pas, vous auriez à recourir à la hack minuterie (ce qui peut provoquer d'autres problèmes de synchronisation comme rejetant la boîte de dialogue plus tard).

Bien sûr, si vous pouvez utiliser this ou ActivityName.this, il est plus stable car this pointe déjà à quelque chose. Mais dans certains cas, comme avec certaines architectures Fragment, ce n'est pas une option.

(Pour les références futures)

Je pense qu'il est parce qu'il ya des différences dans leur contexte d'application et contexte d'activité, comme expliqué ici: http: //www.doubleencore.com/2013/06/context/

Ce qui signifie que nous ne pouvons pas montrer de dialogue à l'aide du contexte d'application. Voilà.

Pour utiliser les boîtes de dialogue à l'intérieur des activités, faites-le de cette façon:

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
     //...
}

Pour utiliser les boîtes de dialogue à l'intérieur de fragments, faites-le de cette façon:

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

Ca y est ^ _ ^

Ce que je l'ai fait pour contourner c'était de créer une classe de base pour toutes mes activités où je stocke des données globales. Dans la première activité, j'ai sauvé le contexte dans une variable dans ma classe de base comme ceci:

classe de base

public static Context myucontext; 

Première activité dérivée de la classe de base

mycontext = this

Puis-je utiliser mycontext au lieu de getApplicationContext lors de la création des boîtes de dialogue.

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

Si vous appelez ProgressDialog.show () dans un fragment, la coulée mContext à l'activité a fonctionné pour moi.

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

J'ai mis en alerte Boîte de dialogue pour lancer exception à la activitty actuelle view.Whenever j'avais donné comme ceci

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

Compte tenu de la même fenêtre Exception.I écrire du code pour recevoir une alerte de onCreate (). Si simple je context = this; après déclaration setContentView() dans la variable onCreate() method.Taken contexte que mondial comme Context context;

Exemple de code est

static Context context;

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


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

        context = this;
.......

Méthode d'alerte échantillon est

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

Il fonctionne très bien pour me.Actually que je recherchais cette erreur sur StackOverflow J'ai trouvé ce query.After lire toutes les réponses de ce post, j'ai essayé de cette façon Il fonctionne .Je pense que c'est une solution simple pour surmonter l'exception.

Merci, Rajendar

si vous avez un problème sur groupActivity DonT utiliser. PARENT est statique du parent ActivityGroup.

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

au lieu de

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

Une boîte de dialogue est toujours créée et affichée comme une partie d'une activité. Vous devez passer dans un contexte d'activité au lieu du contexte d'application.

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

Ceci est un problème commun. Utilisez this au lieu de getApplicationContext() Cela devrait résoudre votre problème

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top