Android 1.6: "android.вид.WindowManager$BadTokenException: невозможно добавить окно-токен null не для приложения"


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

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 переменная кажется, что она правильно заполнена в отладчике.

16 291

16 ответов:

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

Я был укушен этим сегодня тоже, раздражающая часть getApplicationContext() дословно от developer.android.com : (

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

то же самое на getApplicationContext вещь.

документы на сайте Android сказано, чтобы использовать его, но он не работает...гррррр : - П

Так же:

dialog = new Dialog(this); 

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

Android documents предлагает использовать getApplicationContext ();

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

Ex:

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() при объявлении dialouge

всегда использовать 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);
}

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

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

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

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" в AsyncTask, избегая проблемы утечки памяти, - использовать "обработчик" с Looper.главный.)(

    private ProgressDialog tProgressDialog;

затем в "onCreate"

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

Теперь вы r сделали с частью установки. Теперь вызовите ' showProgress () 'и' hideProgress () ' в 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);
    }