Android 1.6: „android.view.WindowManager $ BadTokenException: Nicht imstande, Fenster hinzuzufügen - Token null ist nicht für eine Anwendung“

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

Frage

Ich versuche, ein Dialogfenster zu öffnen, aber jedes Mal, wenn ich versuche, es zu öffnen, führt es diese Ausnahme:

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)

Ich schaffe es durch showDialog mit der Anzeige der ID aufrufen. Der onCreateDialog Handler protokolliert fein und ich kann ohne ein Problem durch Schritt, aber ich habe es angebracht, da es scheint, wie ich etwas fehlt:

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

Gibt es etwas von diesem fehlt? Einige Fragen haben darüber gesprochen, dieses Problem zu haben, wenn ein Dialog von onCreate zu schaffen, die geschieht, weil die Aktivität noch nicht erstellt, aber das kommt von einem Anruf von einem Menüobjekt und die appContext Variable scheint, wie es richtig in die bevölkert Debugger.

War es hilfreich?

Lösung

Statt: Context appContext = this.getApplicationContext(); Sie sollten einen Zeiger auf die Aktivität verwenden Sie sind in (wahrscheinlich this).

ich dies auch heute gebissen wurde, das lästige Teil ist die getApplicationContext() ist wörtlich aus developer.android.com: (

Andere Tipps

Sie können ein Anwendungsfenster / Dialog über einen Kontext angezeigt werden, die keine Aktivität ist. Versuchen Sie eine gültige Aktivität Referenz geben

Ditto auf der getApplicationContext Sache.

Die Dokumente auf der Android-Website sagen, es zu benutzen, aber es funktioniert nicht ... grrrrr :-P

Just tun:

dialog = new Dialog(this); 

"this" ist in der Regel Ihre Aktivität, von dem Sie den Dialog starten.

Android Dokumente schlagen getApplicationContext zu verwenden ();

, aber es wird nicht anstelle dieser Nutzung Ihre aktuelle Tätigkeit arbeiten, während AlertDialog.Builder oder Alertdialog oder Dialog Instanziieren ...

Beispiel:

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

oder

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

Statt getApplicationContext(), benutzen Sie einfach ActivityName.this

Ich hatte ein ähnliches Problem, bei dem ich so einem anderen Klasse etwas hatte:

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

hat gut funktioniert die meiste Zeit, aber manchmal abgestürzt es mit dem gleichen Fehler. Dann merke ich, dass in MyActivity I had ...

public class MyActivity extends Activity {
  public static Something something;

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

Weil ich das Objekt als static hielt, ein zweiter Durchlauf des Codes noch wurde die ursprüngliche Version des Objekts zu halten, und damit immer noch unter Bezugnahme auf die ursprüngliche Activity, das nicht lange existiert.

Dumme dumme Fehler, vor allem weil ich wirklich nicht das Objekt als static in erster Linie werden musste halten ...

Einfach in verändern

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

Anstelle von

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

Eine andere Lösung ist es, den Fenstertyp auf ein System Dialog zu setzen:

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

Dies erfordert die SYSTEM_ALERT_WINDOW Erlaubnis:

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

Wie die docs sagen:

  

sollten nur sehr wenige Anwendungen, die diese Erlaubnis verwenden; Diese Fenster sind für System-Level-Interaktion mit dem Benutzer.

Dies ist eine Lösung, die Sie sollten nur verwendet werden, wenn Sie einen Dialog benötigen, die nicht auf eine Tätigkeit gebunden sind.

Verwenden Sie getApplicationContext() nicht erklären dialouge

Verwenden Sie immer this oder Ihre activity.this

Das ist für mich gearbeitet -

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

Mit

ActivityName.this

Für verschachtelte Dialoge dieses Problem sehr häufig, es funktioniert, wenn

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

wird verwendet, anstelle von

mDialogBuilder = new AlertDialog.Builder(getApplicationContext);

diese Alternative.

Sie können dies auch tun

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

Das ist für mich gearbeitet !!

Wie gesagt, müssen Sie eine Tätigkeit als Rahmen für den Dialog, die Verwendung „YourActivity.this“ für einen statischen Kontext oder überprüfen hier wie eine dynamische in einem sicheren Modus verwenden

Versuchen dialog Fensters Typ

zurücksetzen
WindowManager.LayoutParams.TYPE_SYSTEM_ALERT:
dialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);

Vergessen Sie nicht die Erlaubnis android.permission.SYSTEM_ALERT_WINDOW verwenden

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

Text hier: -
verwenden diese Option, um activity Kontext für progressdialog

 progressdialog = new ProgressDialog(Splash.this);

oder progressdialog = new ProgressDialog(this);

verwenden diese Option, um Anwendungskontext für BroadcastListener      nicht für progressdialog.

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

Die beste und sicherste Weg, um eine ‚ProgressDialog‘ in einem AsyncTask zu zeigen, Speicherverlust Problem zu vermeiden, ist ein ‚Handler‘ mit Looper.main () zu verwenden.

    private ProgressDialog tProgressDialog;

dann in der 'onCreate'

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

Jetzt r Sie mit dem Setup-Teil getan. Nun rufen 'Showprogress ()' und '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);
    }
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top