web-dev-qa-db-de.com

Android 1.6: "Android.view.WindowManager $ BadTokenException: Fenster kann nicht hinzugefügt werden - Token null ist nicht für eine Anwendung"

Ich versuche, ein Dialogfenster zu öffnen, aber jedes Mal, wenn ich versuche, es zu öffnen, wird die folgende Ausnahme ausgelöst:

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 erstelle es, indem ich showDialog mit der ID des Displays aufrufe. Der onCreateDialog -Handler protokolliert problemlos und ich kann ihn ohne Probleme durchgehen, aber ich habe ihn angehängt, da mir anscheinend 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;      
}

Fehlt hier etwas? In einigen Fragen wurde davon gesprochen, dass dieses Problem beim Erstellen eines Dialogfelds aus onCreate aufgetreten ist. Dies geschieht, weil die Aktivität noch nicht erstellt wurde. Dies stammt jedoch von einem Aufruf eines Menüobjekts, und die Variable appContext scheint, als wäre sie richtig in der Datenbank gefüllt Debugger.

296
Dan Monego

Anstelle von: Context appContext = this.getApplicationContext(); sollten Sie einen Zeiger auf die Aktivität verwenden, in der Sie sich befinden (wahrscheinlich this).

Ich bin auch heute davon gebissen worden, der ärgerliche Teil ist, dass getApplicationContext() vom Entwickler verbatim ist.Android.com :(

608
Torp

Sie können ein Anwendungsfenster/ein Dialogfeld nicht über einen Kontext anzeigen, der keine Aktivität ist. Versuchen Sie, eine gültige Aktivitätsreferenz zu übergeben

78
Samuh

Das Gleiche gilt für die getApplicationContext-Sache.

In den Dokumenten auf der Android-Site heißt es, es zu verwenden, aber es funktioniert nicht ... grrrrr :-P

Mach einfach:

dialog = new Dialog(this); 

"this" ist normalerweise Ihre Aktivität, von der aus Sie den Dialog starten.

45
kenyee

Android-Dokumente schlagen vor, getApplicationContext () zu verwenden.

es funktioniert jedoch nicht, sondern verwendet Ihre aktuelle Aktivität, während AlertDialog.Builder oder AlertDialog oder Dialog instanziiert wird 

Ex: 

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

oder

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

Verwenden Sie statt getApplicationContext() einfach ActivityName.this.

17
mahbub_siddique

Ich hatte ein ähnliches Problem, bei dem ich eine andere Klasse hatte, etwa so:

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

Die meiste Zeit funktionierte gut, aber manchmal stürzte es mit demselben Fehler ab. Dann merke ich, dass ich in MyActivity hatte ...

public class MyActivity extends Activity {
  public static Something something;

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

Da ich das Objekt als static hielt, hielt ein zweiter Lauf des Codes immer noch die ursprüngliche Version des Objekts und bezog sich somit immer noch auf die ursprüngliche Activity, die nicht mehr existierte.

Dummer dummer Fehler, zumal ich das Objekt eigentlich gar nicht als static halten musste ...

13
T.Hawk

Ändern Sie es einfach in

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

Anstatt

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

Eine andere Lösung besteht darin, den Fenstertyp auf einen Systemdialog festzulegen:

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

Dies erfordert die Berechtigung SYSTEM_ALERT_WINDOW :

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

Wie die Dokumente sagen:

Sehr wenige Anwendungen sollten diese Erlaubnis verwenden. Diese Fenster sind für die Interaktion mit dem Benutzer auf Systemebene vorgesehen.

Dies ist eine Lösung, die Sie nur verwenden sollten, wenn Sie ein Dialogfeld benötigen, das nicht an eine Aktivität angehängt ist.

9
Anubian Noob

Verwenden Sie getApplicationContext() nicht zur Deklaration von Dialouges

Verwenden Sie immer this oder Ihren activity.this 

4
Jinu

Dies funktionierte für mich--

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

Benutzen 

ActivityName.this
3
Suyog Gunjal

Bei verschachtelten Dialogen ist dieses Problem sehr häufig. Es funktioniert, wenn 

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

wird anstelle von verwendet 

mDialogBuilder = new AlertDialog.Builder(getApplicationContext);

diese Alternative.

2
mifthi

Sie können das auch tun 

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

Das hat für mich funktioniert !! 

1
Metalhead1247
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 Sie diese Option, um activity-Kontext für progressdialog abzurufen.

 progressdialog = new ProgressDialog(Splash.this);

oder progressdialog = new ProgressDialog(this); 

verwenden Sie diese Option, um den Anwendungskontext für BroadcastListener.__ abzurufen. nicht für progressdialog.

progressdialog = new ProgressDialog(getApplicationContext());
progressdialog = new ProgressDialog(getBaseContext());
0
Faisal Ashraf

Versuchen Sie, den Typ von dialog window auf zurückzusetzen

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

Vergessen Sie nicht, die Erlaubnis zu verwenden, Android.permission.SYSTEM_ALERT_WINDOW

0
hopetribe

Wie gesagt, Sie benötigen eine Aktivität als Kontext für den Dialog, verwenden Sie "YourActivity.this" für einen statischen Kontext oder prüfen Sie hier , wie Sie einen dynamischen in einem sicheren Modus verwenden

0
Hugo

Der beste und sicherste Weg, einen 'ProgressDialog' in einer AsyncTask anzuzeigen, um ein Speicherleckproblem zu vermeiden, ist die Verwendung eines 'Handlers' mit Looper.main ().

    private ProgressDialog tProgressDialog;

dann in der 'onCreate'

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

Nun sind Sie mit dem Setup-Teil fertig. Rufen Sie nun in asyncTask 'showProgress ()' und 'hideProgress ()' auf.

    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);
    }
0
Sankar Behera