Android 1.6: "android.vue.WindowManager $ BadTokenException: impossible d'ajouter window-token null n'est pas pour une application"

j'essaie 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 le crée en appelant showDialog avec l'identifiant de l'écran. Le gestionnaire onCreateDialog se connecte très bien et je peux passer à travers sans problème, mais je l'ai attaché car 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;      
}

il manque quelque chose? Certaines questions ont parlé d'avoir ce problème quand créer une boîte de dialogue à partir de onCreate , ce qui arrive parce que l'activité n'est pas encore créée, mais cela vient d'un appel d'un objet menu, et la variable appContext semble être correctement générée dans le débogueur.

291
demandé sur JJD 2010-04-14 08:55:13

16 réponses

au lieu de : Context appContext = this.getApplicationContext(); vous devriez utiliser un pointeur vers l'activité dans laquelle vous êtes (probablement this ).

j'ai été mordu par ceci aujourd'hui aussi, la partie ennuyeuse est le getApplicationContext() est mot à mot de developer.android.com : (

607
répondu Torp 2018-01-19 07:34:38

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

77
répondu Samuh 2010-04-14 06:44:12

idem sur le truc du context getapplication.

les documents sur le site android dit de l'utiliser, mais il ne fonctionne pas...grrrrrrr: - p

Just do:

dialog = new Dialog(this); 

"ce" est généralement de votre Activité à partir de laquelle vous lancez la boîte de dialogue.

45
répondu kenyee 2013-07-18 12:34:20

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

mais il ne fonctionnera pas à la place de que l'utilisation de votre activité actuelle tout en instantiating AlertDialog.Constructeur ou AlertDialog ou Dialog...

Ex:

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

ou

AlertDialog.Builder builder = new  AlertDialog.Builder((Your Activity).this);
43
répondu Pradeep 2013-07-18 12:17:32

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

17
répondu mahbub_siddique 2015-04-23 10:53:27

j'ai eu un problème similaire où j'avais une autre classe quelque chose 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();
  }
}

fonctionnait bien la plupart du temps, mais parfois il s'est écrasé avec la même erreur. Puis je me rends compte que dans MyActivity j'avais...

public class MyActivity extends Activity {
  public static Something something;

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

parce que je tenais l'objet comme static , un deuxième passage du code tenait toujours la version originale de l'objet, et donc se référait toujours à l'original Activity , qui ne fut pas long exister.

Stupide erreur, d'autant plus que je n'avais pas vraiment besoin de tenir l'objet comme static en premier lieu...

13
répondu T.Hawk 2011-08-03 13:52:28

il suffit de le changer en

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

au lieu de

AlertDialog.Builder alert_Categoryitem = 
    new AlertDialog.Builder(getApplicationContext());
12
répondu Satheesh 2013-11-22 17:04:14

une autre solution consiste à définir le type de fenêtre dans une boîte de dialogue Système:

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

cela nécessite la SYSTEM_ALERT_WINDOW permission:

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

comme disent les docs:

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

Cette solution ne doit être utilisée que si vous avez besoin d'un dialogue qui n'est pas attaché à une activité.

9
répondu Anubian Noob 2015-07-13 16:02:15

Ne pas utiliser getApplicationContext() , déclarant dialouge

utilisez toujours this ou votre activity.this

4
répondu Jinu 2015-03-04 11:35:35

ça 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();

Utiliser

ActivityName.this
3
répondu Suyog Gunjal 2015-12-06 10:31:26

pour dialogues emboîtés ce problème est très courant, il fonctionne quand

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

est utilisé à la place de

mDialogBuilder = new AlertDialog.Builder(getApplicationContext);

cette alternative.

2
répondu mifthi 2014-08-25 17:18:44

, Vous pouvez aussi le faire

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

ça a marché pour moi !!

1
répondu Metalhead1247 2013-11-22 17:04:45

comme il est dit, vous avez besoin d'une activité comme contexte pour le dialogue, utilisez" votre activité.ceci" pour un contexte statique ou cochez ici pour savoir comment utiliser un contexte dynamique en mode de sécurité

0
répondu Hugo 2017-05-23 11:47:18

essayer de réinitialiser dialog type de fenêtre à

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

N'oubliez pas d'utiliser la permission android.permission.SYSTEM_ALERT_WINDOW

0
répondu hopetribe 2017-01-16 13:26:58
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);
//                          }
        });
    }

ici le Texte:-

utilisez ceci pour obtenir le contexte activity pour progressdialog

 progressdialog = new ProgressDialog(Splash.this);

ou progressdialog = new ProgressDialog(this);

utilisez ceci pour obtenir le contexte d'application pour BroadcastListener pas pour progressdialog .

progressdialog = new ProgressDialog(getApplicationContext());
progressdialog = new ProgressDialog(getBaseContext());
0
répondu Faisal Ashraf 2017-01-16 13:42:46

la meilleure et la plus sûre façon de montrer un 'ProgressDialog' dans un AsyncTask, en évitant le problème de fuite de mémoire est d'utiliser un 'Handler' avec Looper.principal.)(

    private ProgressDialog tProgressDialog;

puis dans le "onCreate "

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

Maintenant vous avez fini avec la partie setup. 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);
    }
0
répondu Sankar Behera 2017-02-23 08:09:30