Android 1.6: «Android.View.windowManager $ BadtokenException: невозможно добавить окно - токен NULL не для приложения»

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

Вопрос

Я пытаюсь открыть диалоговое окно, но каждый раз, когда я пытаюсь открыть его, он бросает это исключение:

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)

Я создаю это, позвонив showDialog с идентификатором дисплея. То onCreateDialog Обработчик логит хорошо, и я могу пройти через него без проблем, но я прикрепил его, так как кажется, что я что-то упускаю:

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

Есть ли что-то от этого? Некоторые вопросы говорили об этой проблеме при создании диалога из onCreate, что происходит, потому что активность еще не создана, но это исходит из вызова из объекта меню, а appContext Переменная кажется, что она правильно заполнена в отладчике.

Это было полезно?

Решение

Вместо :Context appContext = this.getApplicationContext();Вы должны использовать указатель на деятельность, в которой вы находитесь (возможно, this).

Я тоже укусил это сегодня, раздражающая часть getApplicationContext() Verbatim от Developer.Android.com :(

Другие советы

Вы не можете отобразить окно / диалоговое окно приложения через контекст, который не является активностью. Попробуйте пройти допустимую ссылку на активность

То же самое на GetaplicationContext вещь.

Документы на сайте Android говорят, что это использовать, но это не работает ... grrrrr :-p

Просто делать:

dialog = new Dialog(this); 

"это" Обычно ваша активность, из которой вы запускаете диалог.

Android-документы предлагают использовать GetapplicationContext ();

Но вместо этого не будет работать, что использует вашу текущую активность во время создания AlertDialog.Builder или AlertDialog или Dialog ...

Бывший:

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

или

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

Вместо getApplicationContext(), просто используйте ActivityName.this

У меня была подобная проблема, где у меня был другой класс что-то вроде этого:

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

Работал нормально большую часть времени, но иногда он разбился с той же ошибкой. Тогда я понимаю, что в MyActivity Я имел...

public class MyActivity extends Activity {
  public static Something something;

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

Потому что я держал объект как static, второй пробег кода все еще удерживал оригинальную версию объекта, и поэтому все еще имел в виду оригинал Activity, который не давно не существовал.

Глупо глупая ошибка, тем более, что мне действительно не нужно было держать объект как static в первую очередь...

Просто измените это в

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

Вместо

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

Другое решение - установить тип окна в диалоговое окно системы:

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

Это требует SYSTEM_ALERT_WINDOW разрешение:

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

Как говорят документы:

Очень немногие приложения должны использовать это разрешение; Эти окна предназначены для взаимодействия на уровне системы с пользователем.

Это решение, которое вы должны использовать только в том случае, если вам требуется диалог, который не прикреплен к активности.

Не используйте getApplicationContext() на объявлении диалога

Всегда используйте this или ваш activity.this

Это работало для меня ...

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

Использовать

ActivityName.this

Для вложенных диалогов эта проблема очень распространена, работает, когда

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

используется вместо

mDialogBuilder = new AlertDialog.Builder(getApplicationContext);

эта альтернатива.

Вы также можете сделать это

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

Это работало для меня !!

Как сказано, вам нужна деятельность в качестве контекста для диалогового окна, используйте «Youractive.this» для статического контекста или проверки здесь Для того, как использовать динамический в безопасном режиме

Попробуйте сбросить dialog тип окна до

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

Не забудьте использовать разрешение android.permission.SYSTEM_ALERT_WINDOW

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

Текст здесь: -
Используйте это для получения activity контекст для progressdialog

 progressdialog = new ProgressDialog(Splash.this);

или progressdialog = new ProgressDialog(this);

Используйте это для получения контекста приложения для BroadcastListenerне для progressdialog.

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

Лучший и самый безопасный способ показать «ProgressDialog» в асинктике, избегая проблемы утечки памяти - использовать «обработчик» с Looper.main ().

    private ProgressDialog tProgressDialog;

Тогда в «Oncreate»

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

Теперь вы сделали с деталью настройки. Теперь позвоните «ShowProgress ()» и «HideProgress ()» в асинктракске.

    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);
    }
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top