"Android.view.WindowManager $ BadTokenException: Imansible aggiungere la window" su buider.show ()

Dalla mia attività principale, devo call una class interna e in un metodo all'interno della class, ho bisogno di mostrare AlertDialg e di respingerlo quando premere OK e inoltrare a Google Play per l'acquisto.

Le cose funzionano perfettamente per la maggior parte delle volte, ma per pochi utenti si blocca su builder.show() e posso vedere "android.view.WindowManager$BadTokenException: Imansible aggiungere la window" dal registro di incidenti. Vi prego di suggerire.

  • Applica un'animation a più viste contemporaneamente
  • Il hash chiave non corrisponde mentre il login facebook in android
  • ListView scorrere fino all'elemento selezionato
  • Invio di intenti di posta elettronica HTML senza l'eliminazione di <img>
  • Notifica Android dopo l'applicazione è installata sul dispositivo - come fare?
  • Strano exception: non è ansible lanciare String in Boolean quando si utilizza getBoolean
  • Il mio codice è molto simile a questo:

     public class classname1 extends Activity{ public void onCreate(Bundle savedInstanceState) { this.requestWindowFeature(Window.FEATURE_NO_TITLE); super.onCreate(savedInstanceState); setContentView(R.layout.<view>); //call the <className1> class to execute } private class classNamename2 extends AsyncTask<String, Void, String>{ protected String doInBackground(String... params) { } protected void onPostExecute(String result){ if(page.contains("error")) { AlertDialog.Builder builder = new AlertDialog.Builder(classname1.this); builder.setCancelable(true); builder.setMessage(""); builder.setInverseBackgroundForced(true); builder.setNeutralButton("Ok",new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int whichButton){ dialog.dismiss(); if(!<condition>) { try { String pl = ""; mHelper.<flow>(<class>.this, SKU, RC_REQUEST, <listener>, pl); } catch(Exception e) { e.printStackTrace(); } } } }); builder.show(); } } } } 

    Ho anche visto l'errore in un altro avviso in cui non sto inoltro ad alcuna altra attività. È così semplice:

     AlertDialog.Builder builder = new AlertDialog.Builder(classname1.this); builder.setCancelable(true); //if successful builder.setMessage(" "); builder.setInverseBackgroundForced(true); builder.setNeutralButton("Ok",new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int whichButton){ // dialog.dismiss(); } }); builder.show(); } 

  • Il video gioca una sola volta in Webview di Android
  • GPS non aggiornare la posizione dopo la chiusura e riaprire l'applicazione su android
  • Android - come ricevere le intenzioni di trasmissione ACTION_SCREEN_ON / OFF?
  • differenza tra rawquery e execSQL nel database sqlite android
  • Android installa il filesystem con l'authorization di scrittura
  • Android recyclerView findViewHolderForAdapterPosition restituisce null
  • 8 Solutions collect form web for “"Android.view.WindowManager $ BadTokenException: Imansible aggiungere la window" su buider.show ()”

     android.view.WindowManager$BadTokenException: Unable to add window" 

    Problema:

    Questa exception si verifica quando l'applicazione sta tentando di informare l'utente dal thread di background (AsyncTask) aprendo un dialogo.

    Se si sta tentando di modificare l'interface utente dal thread di background (di solito da OnPostExecute () di AsyncTask) e se l'attività entra nella fase di finitura ovvero esplicitamente chiamando finitura (), l'utente premendo il button Home o Back o l'attività di pulizia fatta da Android allora get questo errore.

    Motivo:

    La ragione di questa exception è che, come dice il messaggio di exception, l'attività è terminata ma si sta tentando di visualizzare una window di dialogo con un context dell'attività finita. Dal momento che non esiste una window per la window di dialogo per visualizzare il runtime android, questa exception viene lanciata.

    Soluzione:

    Utilizza il metodo isFinishing() che viene chiamato da Android per verificare se questa attività è in fase di finitura: sia che si tratti di chiusura esplicita () o di un'attività di pulizia effettuata da Android. Utilizzando questo metodo è molto facile evitare l'apertura di dialogo dal thread di background quando l'attività è terminata.

    Inoltre mantenere un weak reference per l'attività (e non un riferimento forte in modo che l'attività possa essere distrutta una volta che non sia necessaria) e controllare se l'attività non è terminata prima di eseguire qualsiasi interface utente utilizzando questo riferimento di attività (vale a dire mostrare una window di dialogo).

    ad esempio .

     private class chkSubscription extends AsyncTask<String, Void, String>{ private final WeakReference<login> loginActivityWeakRef; public chkSubscription (login loginActivity) { super(); this.loginActivityWeakRef= new WeakReference<login >(loginActivity) } protected String doInBackground(String... params) { //web service call } protected void onPostExecute(String result) { if(page.contains("error")) //when not subscribed { if (loginActivityWeakRef.get() != null && !loginActivityWeakRef.get().isFinishing()) { AlertDialog.Builder builder = new AlertDialog.Builder(login.this); builder.setCancelable(true); builder.setMessage(sucObject); builder.setInverseBackgroundForced(true); builder.setNeutralButton("Ok",new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int whichButton){ dialog.dismiss(); } }); builder.show(); } } } } 

    Aggiornare :

    Gettoni da window:

    Come suggerisce il suo nome, un token di window è un tipo speciale di token che il gestore di window utilizza per identificare in modo univoco una window del sistema. I segnalini di window sono importnti per la sicurezza perché rendono imansible per le applicazioni dannose disegnare in cima alle windows delle altre applicazioni. Il gestore di window protegge da questo richiedendo alle applicazioni di passare il token di window dell'applicazione come parte di each richiesta di aggiungere o rimuovere una window. Se i token non corrispondono, il gestore di window rifiuta la richiesta e genera una BadTokenException . Senza i gettoni di window, questo passaggio di identificazione necessario non sarebbe ansible e il gestore di window non sarebbe in grado di proteggersi da applicazioni dannose.

    Uno scenario del mondo reale:

    Quando un'applicazione viene avviata per la prima volta, ActivityManagerService crea un tipo speciale di token della window chiamato un token della window dell'applicazione, che identifica in modo univoco la window del contenitore di livello superiore dell'applicazione. Il gestore di attività fornisce questo token sia all'applicazione che al gestore di window e l'applicazione invia il token al gestore di window each volta che vuole aggiungere una nuova window allo schermo. Ciò assicura un'interazione sicura tra l'applicazione e il gestore di window (rendendo imansible aggiungere windows alle altre applicazioni) e rende anche facile per il gestore attività di fare richieste dirette al gestore di window.

    La ragione ansible è il context della window di avviso. Puoi essere finita quell'attività in modo che il suo tentativo di aprire in quel context ma che sia già chiuso. Prova a cambiare il context di questa window di dialogo prima che tu non sarai finito fino alla fine.

    per esempio

    piuttosto che questo.

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

    cercare di utilizzare

     AlertDialog alertDialog = new AlertDialog.Builder(FirstActivity.getInstance()).create(); 

    Ho avuto dialogo che mostra la function:

     void showDialog(){ new AlertDialog.Builder(MyActivity.this) ... .show(); } 

    Stavo ricevendo questo errore e isFinishing() controllare isFinishing() prima di call questa window di dialogo che mostra la function.

     if(!isFinishing()) showDialog(); 
    • in primo luogo non è ansible estendere AsyncTask senza override doInBackground
    • innanzitutto cercare di creare AlterDailog dal constructor quindi call show ().

       private boolean visible = false; class chkSubscription extends AsyncTask<String, Void, String> { protected void onPostExecute(String result) { AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this); builder.setCancelable(true); builder.setMessage(sucObject); builder.setInverseBackgroundForced(true); builder.setNeutralButton("Ok", new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int whichButton) { dialog.dismiss(); } }); AlertDialog myAlertDialog = builder.create(); if(visible) myAlertDialog.show(); } @Override protected String doInBackground(String... arg0) { // TODO Auto-generated method stub return null; } } @Override protected void onResume() { // TODO Auto-generated method stub super.onResume(); visible = true; } @Override protected void onStop() { visible = false; super.onStop(); } 

    Sto creando Dialog in onCreate e usandolo con show e hide . Per me la causa principale non stava abbandonando onBackPressed , che stava finendo l'attività Home .

     @Override public void onBackPressed() { new AlertDialog.Builder(this) .setTitle("Really Exit?") .setMessage("Are you sure you want to exit?") .setNegativeButton(android.R.string.no, null) .setPositiveButton(android.R.string.yes, new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { Home.this.finish(); return; } }).create().show(); 

    Stavo finendo la Home Activity onBackPressed senza chiudere / respingere le mie windows di dialogo.

    Quando ho licenziato le mie windows di dialogo, l'incidente è scomparso.

     new AlertDialog.Builder(this) .setTitle("Really Exit?") .setMessage("Are you sure you want to exit?") .setNegativeButton(android.R.string.no, null) .setPositiveButton(android.R.string.yes, new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { networkErrorDialog.dismiss() ; homeLocationErrorDialog.dismiss() ; currentLocationErrorDialog.dismiss() ; Home.this.finish(); return; } }).create().show(); 

    Prova questo :

      public class <class> extends Activity{ private AlertDialog.Builder builder; public void onCreate(Bundle savedInstanceState) { this.requestWindowFeature(Window.FEATURE_NO_TITLE); super.onCreate(savedInstanceState); setContentView(R.layout.<view>); builder = new AlertDialog.Builder(<class>.this); builder.setCancelable(true); builder.setMessage(<message>); builder.setInverseBackgroundForced(true); //call the <className> class to execute } private class <className> extends AsyncTask<String, Void, String>{ protected String doInBackground(String... params) { } protected void onPostExecute(String result){ if(page.contains("error")) //when not subscribed { if(builder!=null){ builder.setNeutralButton("Ok",new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int whichButton){ dialog.dismiss(); if(!<condition>) { try { String pl = ""; mHelper.<flow>(<class>.this, SKU, RC_REQUEST, <listener>, pl); } catch(Exception e) { e.printStackTrace(); } } } }); builder.show(); } } } } 

    con questa idea di variables globali, ho salvato l'istanza MainActivity in onCreate (); Variabile globale di Android

     public class ApplicationController extends Application { public static MainActivity this_MainActivity; } 

    e una window di dialogo aperta come questa. ha funzionato.

     @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // Global Var globals = (ApplicationController) this.getApplication(); globals.this_MainActivity = this; } 

    e in un thread, apro la window di dialogo come questo.

     AlertDialog.Builder alert = new AlertDialog.Builder(globals.this_MainActivity); 
    1. Apri MainActivity
    2. Avviare un thread.
    3. Apri la window di dialogo dal thread -> lavoro.
    4. Fai clic sul button "Indietro" (suCreate verrà chiamato e rimuovi prima MainActivity)
    5. Inizia la nuova attività MainActivity. (e salvare l'istanza in globali)
    6. Apri la window di dialogo dal primo thread -> aprirà e funziona.

    🙂

     AlertDialog.Builder builder = new AlertDialog.Builder(Activity.this); builder.setTitle("Invalid Data"); builder.setMessage("please enter valid name and mobile no."); builder.setPositiveButton("Yes", new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int id) { dialog.cancel (); } }); AlertDialog alertDialog = builder.create(); alertDialog.show(); 
    L'Android è un fan Android di Google, tutto su telefoni Android, Android Wear, Android Dev e applicazioni Android Games e così via.