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);
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
Des idées pourquoi cela se produit? J'appelle cela depuis la méthode onCreate
.
Quelle version de l'API utilisez-vous? Si je ne me trompe pas, le problème a été résolu dans Android 1.6 (API version 4).
Il semble que la référence d'objet que getApplicationContext()
renvoie ne renvoie que des points nuls. Je pense que vous rencontrez un problème similaire à celui que j’avais: une partie du code de la onCreate()
est en cours d’exécution avant la construction de la fenêtre. Cela va être un hack, mais essayez de lancer un nouveau thread en 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 réseau IO). Quelque chose comme ça:
@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
}
J'utilise Android version 2.1 avec API niveau 7. J'ai été confronté à ce problème (ou à un problème similaire) et résolu en utilisant ceci:
Dialog dialog = new Dialog(this);
au lieu de cela:
Dialog dialog = new Dialog(getApplicationContext());
J'espère que cela t'aides :)
Pour moi a changé
builder = new AlertDialog.Builder(getApplicationContext());
à
builder = new AlertDialog.Builder(ThisActivityClassName.this);
Ce qui est étrange, c’est que le premier se trouve dans le didacticiel de Google et que les gens reçoivent une erreur à ce sujet.
Je ne pense pas qu'il s'agisse d'un problème de synchronisation lié à un contexte d'application nul
Essayez d'étendre l'application dans votre application (ou utilisez-la si vous en avez déjà une)
public class MyApp extends Application
Rendre l'instance disponible en tant que singleton privé. C'est jamais nul
private static MyApp appInstance;
Faire un assistant 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 !!
Consultez également la réponse de l'ingénieur Android ici: WindowManager $ BadTokenException
Une des causes de cette erreur est peut-être une tentative d’affichage d’une application fenêtre/dialogue à travers 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 Context, au lieu de Activity.
Après avoir lu les réponses ci-dessus, j’ai trouvé que, pour ma situation, ce qui suit a résolu le problème.
Cela 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 suggérant que le contexte était incorrect, j'ai modifié la méthode getApplicationContext () pour extraire le contexte de la vue transmise aux boutons de la méthode onClick.
myButton.setOnClickListener(new OnClickListener(){
public void onClick(View v) {
MyDialogue dialog = new MyDialogue(v.getContext());
dialog.show();
}
});
Je ne comprends pas tout à fait le fonctionnement de Java, donc je peux me tromper, mais je suppose que dans mon cas particulier, la cause pourrait être liée au fait que le fragment ci-dessus a été défini dans une classe Abstract Activity hérité et utilisé par de nombreuses activités, peut-être que cela a contribué au fait que getApplicationContext () ne renvoie pas un contexte valide? (Juste une supposition).
Je crée une vue cartographique avec des superpositions détaillées. Je créais mon calque détaillé comme ceci depuis mon mapActivity:
OCItemizedOverlay currentLocationOverlay = new OCItemizedOverlay(pin,getApplicationContext);
J'ai constaté que j'obtiendrais l'exception "Android.view.WindowManager $ BadTokenException: impossible d'ajouter une fenêtre - le jeton null n'est pas pour une application" lorsque la méthode onTap de mon itemizedoverlay était déclenchée (lorsque l'emplacement est exploité dans la vue map).
J'ai trouvé que si je passais simplement 'this' à la place de 'getApplicationContext ()' à mon constructeur, le problème disparaissait. Cela semble appuyer la conclusion de alienjazzcat. bizarre.
Pour les activités affichées dans TabActivities, utilisez 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);
au lieu 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)
.
Essayer -
AlertDialog.Builder builder = new AlertDialog.Builder(getParent());
Avait un problème similaire avec (compatibilité) Fragments dans lequel l'utilisation d'un getActivity()
dans ProgressDialog.show()
le bloque. Je conviens que c'est à cause du timing.
Une solution possible:
mContext = getApplicationContext();
if (mContext != null) {
mProgressDialog = ProgressDialog.show(mContext, "", getString(R.string.loading), true);
}
à la place 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 aucune garantie que cela fonctionne, cela réduit simplement les risques d'accident. Si cela ne fonctionne toujours pas, vous devrez recourir au hack de la minuterie (ce qui peut causer d'autres problèmes de minutage, tels que le fait de fermer la boîte de dialogue ultérieurement).
Bien sûr, si vous pouvez utiliser this
ou ActivityName.this
, c'est plus stable car this
pointe déjà sur 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 que c'est parce qu'il y a des différences de contexte d'application et de contexte d'activité, comme expliqué ici: http://www.doubleencore.com/2013/06/context/
Ce qui signifie que nous ne pouvons pas afficher de dialogue à l'aide du contexte d'application. C'est tout.
Pour utiliser les dialogues dans les activités, procédez comme suit:
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 des dialogues à l'intérieur de fragments, procédez comme suit:
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;
}
C'est ça ^ _ ^
Pour résoudre ce problème, j'ai créé une classe de base pour toutes mes activités où je stockais des données globales. Dans la première activité, j'ai enregistré le contexte dans une variable de ma classe de base, comme suit:
Classe de base
public static Context myucontext;
Première activité dérivée de la classe de base
mycontext = this
Ensuite, j'utilise mycontext au lieu de getApplicationContext lors de la création de boîtes de dialogue.
AlertDialog alertDialog = new AlertDialog.Builder(mycontext).create();
Si vous appelez ProgressDialog.show () dans un fragment, la conversion du mContext en activité a fonctionné pour moi.
ProgressDialog pd = new ProgressDialog((Activity) mContext);
si vous avez un problème avec le groupe Activité, n'utilisez pas ceci . PARENT est un élément statique du groupe d'activités parent.
final AlertDialog.Builder builder = new AlertDialog.Builder(GroupActivityParent.PARENT);
au lieu de
final AlertDialog.Builder builder = new AlertDialog.Builder(getParent());
C’est un problème courant… .. Utilisez this
au lieu de getApplicationContext()
Une boîte de dialogue est toujours créée et affichée dans le cadre 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
J'ai implémenté Alert Dialog pour une exception avec la vue d'activité en cours. Chaque fois que j'avais donné ceci
AlertDialog.Builder builder = new AlertDialog.Builder(context);
Étant donné la même fenêtre Exception.J'ai écrit du code pour l'alerte à partir de onCreate (). Si simple, j'ai utilisé context = this;
après l'instruction setContentView()
dans la méthode onCreate()
. Variable de contexte pris comme aussi global que Context context;
L'échantillon 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 Sample is
private void alertException(String execMsg){
Log.i(TAG,"in alertException()..."+context);
Log.e(TAG,"Exception :"+execMsg);
AlertDialog.Builder builder = new AlertDialog.Builder(context);
.......
Cela fonctionne bien pour moi.En fait, j'ai recherché cette erreur sur StackOverflow, j'ai trouvé cette requête.Après avoir lu toutes les réponses de ce message, j'ai essayé cette méthode, donc ça marche. Je pensais que c'était une solution simple pour surmonter l'exception.
Merci, Rajendar