J'essaie d'ouvrir une fenêtre de dialogue, mais chaque fois que j'essaie de l'ouvrir, cette exception lève 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 bien et je peux le parcourir 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;
}
Est-ce qu'il manque quelque chose? Certaines questions ont évoqué ce problème lors de la création d’une boîte de dialogue à partir de onCreate
, ce qui est dû au fait que l’activité n’a pas encore été créée, mais provient d’un appel d’un objet de menu et que la variable appContext
semble remplie correctement. débogueur.
Au lieu de: Context appContext = this.getApplicationContext();
vous devriez utiliser un pointeur sur l’activité dans laquelle vous vous trouvez (probablement this
).
Je me suis fait mordre par cela aujourd'hui aussi, la partie ennuyante est la getApplicationContext()
est textuelle de developer.Android.com :(
Vous ne pouvez pas afficher une fenêtre/une boîte de dialogue d'application à travers un contexte qui n'est pas une activité. Essayez de passer une référence d'activité valide
Idem sur la chose getApplicationContext.
Les documents sur le site Android dit de l'utiliser, mais cela ne fonctionne pas ... grrrrr :-P
Il suffit de faire:
dialog = new Dialog(this);
"ceci" est généralement votre activité à partir de laquelle vous lancez le dialogue.
Les documents Android suggèrent d'utiliser getApplicationContext ();
mais cela ne fonctionnera pas au lieu de cela, utilisez votre activité actuelle lors de l'instanciation de 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()
, utilisez simplement ActivityName.this
J'ai eu un problème similaire où j'ai eu une autre classe quelque chose comme ça:
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();
}
}
La plupart du temps, je me suis bien débrouillé, mais il a parfois eu un problème grave. 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
, une deuxième exécution du code contenait toujours la version d'origine de l'objet et faisait donc toujours référence à la Activity
originale, qui n'existait plus.
Erreur stupide et stupide, d'autant plus que je n'avais pas vraiment besoin de tenir l'objet en tant que static
en premier lieu ...
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());
Une autre solution consiste à définir le type de fenêtre sur une boîte de dialogue système:
dialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
Cela nécessite la permission SYSTEM_ALERT_WINDOW
:
<uses-permission Android:name="Android.permission.SYSTEM_ALERT_WINDOW" />
Comme le dit la documentation:
Très peu d'applications devraient utiliser cette permission. ces fenêtres sont conçues pour une interaction au niveau du système avec l'utilisateur.
C'est une solution que vous ne devriez utiliser que si vous avez besoin d'une boîte de dialogue qui n'est pas attachée à une activité.
N'utilisez pas getApplicationContext()
pour déclarer dialouge
Toujours utiliser this
ou votre activity.this
Cela a fonctionné 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();
Utilisation
ActivityName.this
Pour les dialogues imbriqués, ce problème est très courant. Il fonctionne lorsque
AlertDialog.Builder mDialogBuilder = new AlertDialog.Builder(MyActivity.this);
est utilisé à la place de
mDialogBuilder = new AlertDialog.Builder(getApplicationContext);
cette alternative.
Vous pouvez aussi faire ça
public class Example extends Activity {
final Context context = this;
final Dialog dialog = new Dialog(context);
}
Cela a fonctionné pour moi !!
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:-
utilisez ceci pour obtenir le contexte activity
pour progressdialog
progressdialog = new ProgressDialog(Splash.this);
ou progressdialog = new ProgressDialog(this);
utilisez-le pour obtenir le contexte d'application pour BroadcastListener
pas pour progressdialog
.
progressdialog = new ProgressDialog(getApplicationContext());
progressdialog = new ProgressDialog(getBaseContext());
Essayez de réinitialiser le type de fenêtre dialog
à
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
Comme il est dit, vous avez besoin d’une activité en tant que contexte pour la boîte de dialogue, utilisez "YourActivity.this" pour un contexte statique ou cochez ici pour savoir comment utiliser une activité dynamique en mode sans échec.
Le moyen le plus sûr et le plus sûr d'afficher un 'ProgressDialog' dans une tâche asynchrone, en évitant les problèmes de fuite de mémoire, consiste à 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 avez terminé avec la partie configuration. Maintenant, appelez 'showProgress ()' et 'hideProgress ()' en 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);
}