Android 1.6: “android.view.WindowManager $ BadTokenException: Impossibile aggiungere finestra - nulla pedina non è per un'applicazione”

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

Domanda

Sto cercando di aprire una finestra di dialogo, ma ogni volta che provo ad aprirlo che genera questa eccezione:

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)

Sto creando chiamando showDialog con id del display. Il gestore onCreateDialog registra bene e mi può fare un passo attraverso di essa, senza un problema, ma ho attaccato esso in quanto sembra che mi manca qualcosa:

@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;      
}

C'è qualcosa che manca da questo? Alcune domande hanno parlato di avere questo problema quando si crea una finestra di dialogo da onCreate, che avviene perché l'attività non è ancora creata, ma questo viene da una chiamata da un oggetto menu, e la variabile appContext sembra che sia correttamente popolato nel debugger.

È stato utile?

Soluzione

Al posto di: Context appContext = this.getApplicationContext(); si dovrebbe usare un puntatore per l'attività si è in (probabilmente this).

mi sono morso da questo anche oggi, la parte fastidiosa è la getApplicationContext() è pari pari da developer.android.com: (

Altri suggerimenti

Non è possibile visualizzare una finestra / finestra di dialogo dell'applicazione attraverso un contesto che non è un'attività. Prova a passare un riferimento un'attività valida

Idem sulla cosa getApplicationContext.

I documenti sul sito Android dice di usarlo, ma non funziona ... :-P grrrrr

Basta fare:

dialog = new Dialog(this); 

"questo" è di solito la tua attività da cui si avvia la finestra di dialogo.

documenti Android suggerisce di utilizzare getApplicationContext ();

, ma non funzionerà invece che l'uso vostra attività in corso, mentre un'istanza AlertDialog.Builder o AlertDialog o Dialog ...

Esempio:

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

o

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

Invece di getApplicationContext(), basta usare ActivityName.this

Ho avuto un problema simile in cui ho avuto un'altra classe qualcosa di simile:

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();
  }
}

multa lavorato la maggior parte del tempo, ma a volte si è schiantato con lo stesso errore. Poi mi rendo conto che in MyActivity ho avuto ...

public class MyActivity extends Activity {
  public static Something something;

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

Perché avevo in mano l'oggetto come static, una seconda esecuzione del codice è stato ancora in mano la versione originale dell'oggetto, e quindi era ancora riferiva al Activity originale, che non esiste da molto tempo.

sciocco stupido errore, soprattutto perché io davvero non aveva bisogno di essere tenuta l'oggetto come static in primo luogo ...

Basta cambiare in

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

Al posto di

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

Un'altra soluzione è quella di impostare il tipo di finestra per una finestra di sistema:

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

Ciò richiede l'href="http://developer.android.com/reference/android/Manifest.permission.html#SYSTEM_ALERT_WINDOW"> SYSTEM_ALERT_WINDOW permesso

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

Per quanto i documenti dicono:

  

Molto poche applicazioni dovrebbe usare questa autorizzazione; queste finestre sono destinati per l'interazione a livello di sistema con l'utente.

Questa è una soluzione si dovrebbe usare solo se avete bisogno di un dialogo che non è collegato a un'attività.

Non utilizzare getApplicationContext() sulla proclamazione del dialouge

Sempre uso this o il vostro activity.this

Questo ha funzionato per me -

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

Usa

ActivityName.this

Per le finestre di dialogo nidificate questo problema è molto comune, Funziona quando

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

è usato al posto di

mDialogBuilder = new AlertDialog.Builder(getApplicationContext);

questa alternativa.

È anche possibile fare questo

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

Questo ha funzionato per me !!

Come si dice, è necessario un contesto di attività, come per la finestra, usa "YourActivity.this" per un contesto statico o controllare qui per come utilizzare una dinamica in una modalità sicura

Prova a ripristinare il tipo di finestra dialog a

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

Non dimenticare di utilizzare il android.permission.SYSTEM_ALERT_WINDOW autorizzazione

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);
//                          }
        });
    }

Testo qui: -
utilizzare questo per ottenere contesto activity per progressdialog

 progressdialog = new ProgressDialog(Splash.this);

o progressdialog = new ProgressDialog(this);

utilizzare questo per ottenere il contesto applicativo per BroadcastListener      non per progressdialog.

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

Il meglio e il modo più sicuro per mostrare un 'ProgressDialog' in un AsyncTask, evitando problemi di perdita di memoria è di utilizzare un 'Handler' con Looper.main ().

    private ProgressDialog tProgressDialog;

poi nel 'onCreate'

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

Ora si r fatto con la parte di installazione. Ora chiamare 'showProgress ()' e 'hideProgress ()' in 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);
    }
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top