Android 1.6: “android.view.WindowManager $ BadTokenException: Pencere eklenemiyor - simge null bir uygulama için değil”


303

Bir iletişim penceresi açmaya çalışıyorum, ancak her açmaya çalıştığımda bu istisnayı atar:

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)

showDialogGörüntünün kimliğiyle arayarak oluşturuyorum . onCreateDialogİşleyici cezası kaydeder ve ben bir sorun olmadan bunlara adım atabilirsiniz, ama bir şey eksik gibi görünüyor çünkü bunu bağlı olduğunuz:

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

Bundan eksik bir şey var mı? Bazı sorular, bir iletişim kutusu oluştururken bu sorunun yaşandığından bahsetti; bu onCreate, etkinlik henüz oluşturulmadığı için gerçekleşiyor, ancak bu bir menü nesnesinden gelen bir çağrıdan geliyor ve appContextdeğişken, hata ayıklayıcıda doğru şekilde doldurulmuş gibi görünüyor.

Yanıtlar:


609

Bunun yerine: Context appContext = this.getApplicationContext(); içinde bulunduğunuz etkinliğe bir işaretçi kullanmalısınız (muhtemelen this).

Ben de bugün bu tarafından ısırıldı, sinir bozucu kısmı getApplicationContext()geliştirici.android.com bir kelimedir :(


2
Ayrıca bir hata olarak bildirildi (kullanıcı soruyu gönderdiğinde olmamasına rağmen): code.google.com/p/android/issues/detail?id=11199
Raymond Martineau

63
Bunun herkese yardımcı olması durumunda - myActivity.this iletişim kutusunu bağlamınız olarak kullanın.
Rab Ross

13
Bu soru ve cevap 2 günde 3 yaşında. Hala itibar kazanıyorum, bu yüzden Google hala dokümanlarını sabitlemedi ...
Torp


6
Bu, Nisan 2016'dır ve yine de bu istisna, iletişim kutusunun başlatılmasında uygulama çökmesine neden olur.
Yogesh Seralia

78

Etkinlik olmayan bir Bağlam aracılığıyla bir uygulama penceresi / iletişim kutusu görüntüleyemezsiniz. Geçerli bir etkinlik referansı iletmeyi deneyin


Nasıl? Denedim activity.thisve activity.getBaseContext()ancak boşuna. Herhangi bir yardım?
Darpan

3
Anladım. Etkinlik adınızı doğrudan buraya iletin. Olmadan .this.
Darpan

45

GetApplicationContext şey üzerinde Ditto.

Android sitesindeki belgeler kullanmak diyor, ama çalışmıyor ... grrrrr :-P

Sadece yap:

dialog = new Dialog(this); 

"this" genellikle iletişim kutusunu başlattığınız Etkinliğinizdir.


43

Android belgeleri getApplicationContext ();

ancak bunun yerine, AlertDialog.Builder veya AlertDialog veya Dialog'u başlatırken mevcut etkinliğinizi kullanın ...

Ör:

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

veya

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

Bu bana çok yardımcı oldu. Başka bir iletişim kutusundan bir iletişim kutusu oluşturmaya çalışıyordum ve sadece "AlertDialog.Builder (this);" bir hata veriyor. Teşekkürler!
EHarpham

(ActivityName.this) özellikle onClick içinde bir iletişim kutusu oluşturmaya çalışırken yararlıdır
RmK

Benim sorunum bir Adaptör içinde bir AlertDialog içinde bir ProgressDialog inşa olmasıdır ... Çalışmak için alamıyorum.
Martin Erlic


13

Ben böyle bir şey başka bir sınıf vardı benzer bir sorun vardı:

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

Çoğu zaman iyi çalıştı, ancak bazen aynı hatayla çöktü. Sonra anlıyorum kiMyActivity ...

public class MyActivity extends Activity {
  public static Something something;

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

Çünkü nesneyi static , kodun ikinci bir çalışması hala nesnenin orijinal sürümünü tutuyordu ve bu nedenle hala Activityuzun süredir var olmayan orijinaline atıfta bulunuyordu .

Aptalca bir hata, özellikle de nesneyi staticilk başta olduğu gibi tutmam gerekmediği için ...


12

Sadece değiştirin

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

Onun yerine

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

9

Başka bir çözüm, pencere türünü bir sistem iletişim kutusuna ayarlamaktır:

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

Bu SYSTEM_ALERT_WINDOWizin gerektirir :

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

Dokümanların dediği gibi:

Çok az uygulama bu izni kullanmalıdır; bu pencereler kullanıcıyla sistem düzeyinde etkileşim için tasarlanmıştır.

Bu, yalnızca bir etkinliğe bağlı olmayan bir iletişim kutusuna ihtiyacınız varsa kullanmanız gereken bir çözümdür.


Bu şimdi API 26 düzeyindeki kullanımdan kaldırılmıştır. Geliştiricinin, kullanıcı açısından iyi olmayan sistem penceresiyle oynamasına izin verdiği için.
CopsOnRoad

4

Kullanma getApplicationContext()Diyalog beyanında

Her zaman kullanın thisveyaactivity.this


2

İç içe iletişim kutuları için bu sorun çok yaygındır, Ne zaman çalışır

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

yerine kullanılır

mDialogBuilder = new AlertDialog.Builder(getApplicationContext);

bu alternatif.


2

Bu benim için çalıştı.

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

kullanım

ActivityName.this

0

Bunu da yapabilirsiniz

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

Bu benim için çalıştı !!


0

Deniyor adlı gibi, statik bir bağlam için iletişim, kullanım "YourActivity.this" için bağlam olarak bir Aktivite ihtiyaç veya çek burada güvenli modda dinamik birini nasıl kullanılacağı için


0

dialogPencerenin türünü şu şekilde sıfırlamaya çalışın:

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

İzni kullanmayı unutma android.permission.SYSTEM_ALERT_WINDOW


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

Buraya metin ekleyin: -
için activitybağlam almak için bunu kullanınprogressdialog

 progressdialog = new ProgressDialog(Splash.this);

veya progressdialog = new ProgressDialog(this);

için BroadcastListener değil uygulama bağlamı almak için bunu kullanın progressdialog.

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

0

Bir AsyncTask'ta 'ProgressDialog' göstermenin en iyi ve en güvenli yolu, bellek sızıntısı sorununu önleyerek Looper.main () ile bir 'Handler' kullanmaktır.

    private ProgressDialog tProgressDialog;

sonra 'onCreate'

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

Şimdi kurulum bölümünü tamamladınız. Şimdi AsyncTask'ta 'showProgress ()' ve 'hideProgress ()' öğesini çağırın.

    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);
    }
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.