Android 1.6: « android.view.WindowManager $ BadTokenException: Impossible de fenêtre ajouter - null jeton n'est pas pour une application »

StackOverflow https://stackoverflow.com/questions/2634991

Question

Je suis en train d'ouvrir une fenêtre de dialogue, mais chaque fois que j'essaie de l'ouvrir, il lance cette exception:

Uncaught handler: thread main exiting due to uncaught exception
android.view.WindowManager$BadTokenException: 
     Unable to add window -- token null is not for an application
  at android.view.ViewRoot.setView(ViewRoot.java:460)
  at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:177)
  at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:91)
  at android.app.Dialog.show(Dialog.java:238)
  at android.app.Activity.showDialog(Activity.java:2413)

Je crée en appelant showDialog avec l'identifiant de l'écran. Le gestionnaire de onCreateDialog enregistre bien et je peux parcourir sans un problème, mais je l'ai attaché depuis il semble que je manque quelque chose:

@Override
public Dialog onCreateDialog(int id)
{
    Dialog dialog;
    Context appContext = this.getApplicationContext();
    switch(id)
    {
        case RENAME_DIALOG_ID:
            Log.i("Edit", "Creating rename dialog...");
            dialog = new Dialog(appContext);
            dialog.setContentView(R.layout.rename);
            dialog.setTitle("Rename " + noteName);
            break;
        default:
            dialog = null;
            break;
    }
    return dialog;      
}

Y at-il quelque chose manque à ce sujet? Certaines questions ont parlé d'avoir ce problème lors de la création d'un dialogue à partir onCreate, ce qui arrive parce que l'activité est pas encore créé, mais cela provient d'un appel d'un objet de menu, et la variable appContext semble comme il est rempli correctement dans le débogueur.

Était-ce utile?

La solution

Au lieu de: Context appContext = this.getApplicationContext(); vous devez utiliser un pointeur sur l'activité que vous êtes (probablement this).

Je me suis mordue par aujourd'hui aussi, la partie ennuyeuse est le getApplicationContext() est mot pour mot de developer.android.com: (

Autres conseils

Vous ne pouvez pas afficher une fenêtre de l'application / dialogue dans un contexte qui n'est pas une activité. Essayez de passer une référence d'activité valide

Même chose sur la chose getApplicationContext.

Les documents sur le site Android dit à l'utiliser, mais il ne fonctionne pas ... Grrrrr :-P

Il suffit de faire:

dialog = new Dialog(this); 

"ce" est habituellement votre activité à partir de laquelle vous démarrez la boîte de dialogue.

documents Applications suggère d'utiliser getApplicationContext ();

mais il ne fonctionnera pas au lieu de cette utilisation votre activité actuelle lors de l'instanciation AlertDialog.Builder ou AlertDialog ou Dialog ...

Ex:

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

ou

AlertDialog.Builder builder = new  AlertDialog.Builder((Your Activity).this);

Au lieu de getApplicationContext(), il suffit d'utiliser ActivityName.this

J'ai eu un problème similaire où j'ai eu une autre chose de classe comme ceci:

public class Something {
  MyActivity myActivity;

  public Something(MyActivity myActivity) {
    this.myActivity=myActivity;
  }

  public void someMethod() {
   .
   .
   AlertDialog.Builder builder = new AlertDialog.Builder(myActivity);
   .
   AlertDialog alert = builder.create();
   alert.show();
  }
}

a bien fonctionné la plupart du temps, mais parfois il est écrasé avec la même erreur. Ensuite, je me rends compte que MyActivity I had ...

public class MyActivity extends Activity {
  public static Something something;

  public void someMethod() {
    if (something==null) {
      something=new Something(this);
    }
  }
}

Parce que je retenais l'objet comme static, une deuxième manche du code tenait toujours la version originale de l'objet, et donc était encore référence à la Activity d'origine, qui n'existent depuis longtemps.

idiot erreur stupide, d'autant plus que je ne l'ai pas vraiment besoin d'être maintenant l'objet comme static en premier lieu ...

Il suffit de changer dans

AlertDialog.Builder alert_Categoryitem = 
    new AlertDialog.Builder(YourActivity.this);

Au lieu de

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

Une autre solution consiste à définir le type de fenêtre pour une fenêtre de dialogue du système:

dialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);

Cela nécessite l'autorisation SYSTEM_ALERT_WINDOW :

<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />

Comme les docs disent:

  

Très peu d'applications devraient utiliser cette autorisation; ces fenêtres sont destinées à une interaction au niveau du système avec l'utilisateur.

Ceci est une solution que vous ne devez utiliser si vous avez besoin d'une boîte de dialogue qui n'est pas attaché à une activité.

Ne pas utiliser getApplicationContext() sur la déclaration Dialouge

Toujours utiliser this ou votre activity.this

a marché pour moi -

new AlertDialog.Builder(MainActivity.this)
        .setMessage(Html.fromHtml("<b><i><u>Spread Knowledge Unto The Last</u></i></b>"))
        .setCancelable(false)
        .setPositiveButton("Dismiss",
                new DialogInterface.OnClickListener() {
                    public void onClick(DialogInterface dialog, int id) {
                    }
                }).show();

Utilisez

ActivityName.this

Pour les dialogues imbriqués ce problème est très fréquent, il fonctionne quand

AlertDialog.Builder mDialogBuilder = new AlertDialog.Builder(MyActivity.this);

est utilisé au lieu de

mDialogBuilder = new AlertDialog.Builder(getApplicationContext);

cette alternative.

Vous pouvez aussi le faire

public class Example extends Activity {
    final Context context = this;
    final Dialog dialog = new Dialog(context);
}

Cela a fonctionné pour moi !!

Comme on dit, vous avez besoin d'une activité comme contexte pour la boîte de dialogue, utilisez « YourActivity.this » pour un contexte statique ou consultez ici pour savoir comment utiliser une de dynamique dans un mode sans échec

Essayez de réinitialiser le type de fenêtre dialog à

WindowManager.LayoutParams.TYPE_SYSTEM_ALERT:
dialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);

Ne pas oublier d'utiliser le android.permission.SYSTEM_ALERT_WINDOW d'autorisation

public class Splash extends Activity {

    Location location;
    LocationManager locationManager;
    LocationListener locationlistener;
    ImageView image_view;
    ublic static ProgressDialog progressdialog;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        // TODO Auto-generated method stub
        super.onCreate(savedInstanceState);
        setContentView(R.layout.splash);
        progressdialog = new ProgressDialog(Splash.this);
           image_view.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                // TODO Auto-generated method stub

                        locationManager.requestLocationUpdates("gps", 100000, 1, locationlistener);
                        Toast.makeText(getApplicationContext(), "Getting Location plz wait...", Toast.LENGTH_SHORT).show();

                            progressdialog.setMessage("getting Location");
                            progressdialog.show();
                            Intent intent = new Intent(Splash.this,Show_LatLng.class);
//                          }
        });
    }

Texte ici: -
utiliser pour obtenir le contexte de activity pour progressdialog

 progressdialog = new ProgressDialog(Splash.this);

ou progressdialog = new ProgressDialog(this);

utiliser pour obtenir ce contexte d'application pour BroadcastListener      pas progressdialog.

progressdialog = new ProgressDialog(getApplicationContext());
progressdialog = new ProgressDialog(getBaseContext());

La meilleure et la meilleure façon de montrer un « ProgressDialog » dans un AsyncTask, évitant problème de fuite de mémoire est d'utiliser un « gestionnaire » avec Looper.main ().

    private ProgressDialog tProgressDialog;

puis dans le 'onCreate'

    tProgressDialog = new ProgressDialog(this);
    tProgressDialog.setMessage(getString(R.string.loading));
    tProgressDialog.setIndeterminate(true);

Maintenant, vous r fait avec la partie de l'installation. Maintenant, appelez 'ShowProgress ()' et 'hideProgress ()' dans AsyncTask.

    private void showProgress(){
        new Handler(Looper.getMainLooper()){
            @Override
            public void handleMessage(Message msg) {
                tProgressDialog.show();
            }
        }.sendEmptyMessage(1);
    }

    private void hideProgress(){
        new Handler(Looper.getMainLooper()){
            @Override
            public void handleMessage(Message msg) {
                tProgressDialog.dismiss();
            }
        }.sendEmptyMessage(1);
    }
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top