PopupWindow $ BadTokenException: Не вдається додати вікно - маркер null недійсний


80

У мене є така помилка при відображенні PopupWindow. Помилки викликаються рядком:

checkInPopup.showAtLocation((ViewGroup) mapView.getParent(), Gravity.CENTER_HORIZONTAL, 0, 0);

mapView - це MapView, і ніщо не є нульовим. Трасування стека:

01-08 18:00:09.402: E/AndroidRuntime(27768): Caused by: android.view.WindowManager$BadTokenException: Unable to add window -- token null is not valid; is your activity running?
01-08 18:00:09.402: E/AndroidRuntime(27768):    at android.view.ViewRootImpl.setView(ViewRootImpl.java:513)
01-08 18:00:09.402: E/AndroidRuntime(27768):    at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:301)
01-08 18:00:09.402: E/AndroidRuntime(27768):    at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:215)
01-08 18:00:09.402: E/AndroidRuntime(27768):    at android.view.WindowManagerImpl$CompatModeWrapper.addView(WindowManagerImpl.java:140)
01-08 18:00:09.402: E/AndroidRuntime(27768):    at android.view.Window$LocalWindowManager.addView(Window.java:537)
01-08 18:00:09.402: E/AndroidRuntime(27768):    at android.widget.PopupWindow.invokePopup(PopupWindow.java:988)
01-08 18:00:09.402: E/AndroidRuntime(27768):    at android.widget.PopupWindow.showAtLocation(PopupWindow.java:845)
01-08 18:00:09.402: E/AndroidRuntime(27768):    at android.widget.PopupWindow.showAtLocation(PopupWindow.java:809)
01-08 18:00:09.402: E/AndroidRuntime(27768):    at com.geoloc.ActivityCheckIn.onCreate(ActivityCheckIn.java:50)
01-08 18:00:09.402: E/AndroidRuntime(27768):    at android.app.Activity.performCreate(Activity.java:4465)
01-08 18:00:09.402: E/AndroidRuntime(27768):    at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1049)

Це код моєї діяльності (який розширює MapActivity)

    protected void onCreate(Bundle icicle) {
    super.onCreate(icicle);
    setContentView(R.layout.checkin);
    mapView = (MapView) findViewById(R.id.mapview);

    LayoutInflater inflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    checkInPopup = new PopupWindow(inflater.inflate(CHECK_IN_POPUP_LAYOUT, null, false));
    checkInPopup.setOutsideTouchable(true);
    checkInPopup.setHeight(100);
    checkInPopup.setWidth(200);
    checkInPopup.showAtLocation((ViewGroup) mapView.getParent(), Gravity.CENTER_HORIZONTAL, 0, 0);
}

Дякуємо, що поділилися своїми думками

Відповіді:


71

ви показуєте своє спливаюче вікно занадто рано. Ви можете опублікувати затримку запуску для розміщення шоу в Onresume, спробуйте

Редагувати: Здається, ця публікація відповідає на ту саму проблему. Проблеми зі створенням спливаючого вікна в Android Activity


Я б запропонував зловити виняток і продовжувати розміщувати повідомлення із значною затримкою (принаймні на кілька разів), оскільки початкову затримку передбачити неможливо.
Harsh

93

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

YourActivityName.this замість getApplicationContext()at

Dialog dialog = new Dialog(getApplicationContext());

і так, це працювало для мене, нехай це допоможе комусь іншому


Це мені добре допомогло. Хороша відповідь, дякую
Таруша


10

Існує два сценарії, коли може статися цей виняток. Про одного згадує Нандіш. Інший сценарій згадується тут: http://blackriver.to/2012/08/android-annoying-exception-unable-to-add-window-is-your-activity-running/

Обов’язково працюйте з ними обома


7
Зауважте, що відповіді лише на посилання не рекомендуються, посилання, як правило, застарівають з часом. Будь ласка, додайте сюди окремий конспект, зберігаючи посилання як посилання.
kleopatra

@TheMan Nice ~ така крихітна потужна порада! Дякую!
cmcromance

5
  @Override
protected void onCreate(Bundle savedInstanceState) {
    View view = LayoutInflater.from(mContext).inflate(R.layout.popup_window_layout, new LinearLayout(mContext), true);
    popupWindow = new PopupWindow(view, ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
    popupWindow.setContentView(view);
}

   @Override
public void onWindowFocusChanged(boolean hasFocus) {
    if (hasFocus) {
        popupWindow.showAtLocation(parentView, Gravity.BOTTOM, 0, 0);
    }
}

правильним способом є popupwindow.show () у onWindowFocusChanged ().


Це вирішує проблему вихідного питання і є найкращим / найчистішим рішенням.
Дейл

3

Сам батько спливаючого вікна не може бути спливаючим. Обоє їх батьків повинні бути однаковими. Отже, якщо ви створюєте спливаюче вікно всередині спливаючого вікна, ви повинні зберегти спливаюче вікно батьків і зробити його батьківським.

ось приклад


1

Спробуйте показати поп, як показано нижче

findViewById(R.id.main_layout).post(new Runnable() {
        public void run() {
            mPopupWindow.showAtLocation(findViewById(R.id.main_layout), Gravity.CENTER, 0, 0);
            Button close = (Button) customView.findViewById(R.id.btn_ok);
            close.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    mPopupWindow.dismiss();
                    doOtherStuff();
                }
            });
        }
    });

1

використовуйте цей метод перед шоу

public static ViewGroup getActivityFirstLayout(Context ctx)
{
    return (ViewGroup)((ViewGroup) ActivityMaster.getActivity(ctx).findViewById(android.R.id.content)).getChildAt(0);
}

private boolean activityIsOk(Activity activity)
{
    boolean s1 = !(activity == null || activity.isFinishing());

    if(s1)
    {
        View v = LayoutMaster.getActivityFirstLayout(activity);
        return v.isShown() && ViewCompat.isLaidOut(v);
    }

    return false;
}

0

Спробуйте скористатися ним

LayoutInflater inflater = (LayoutInflater).getApplicationContext().getSystemService(LAYOUT_INFLATER_SERVICE);
View view = inflate.from(YourActivity.this).inflate(R.layout.yourLayout, null);

Не могли б ви також опублікувати повний код, щоб переконатися, що він замінює правильні речі. Дякую.
kwoxer

0

Після багатьох годин пошуку та тестування я знайшов наступне рішення (впроваджуючи різні SO-рішення), ось що не дало збою в будь-якому випадку, я отримував збій.

     Runnable runnable = new Runnable() {
            @Override
            public void run() {

          //displayPopup,progress dialog or what ever action. example

                ProgressDialogBox.setProgressBar(Constants.LOADING,youractivityName.this);
            }};

Там, де logcat вказує, що відбувається збій .. запустіть запущений .в моєму випадку при отриманні трансляції.

runOnUiThread(new Runnable() {
            @Override
            public void run() {
                if(!isFinishing()) {
                    new Handler().postAtTime(runnable,2000);
                }
            }
        });

-1

спробуйте показати таке спливаюче вікно

new Handler().postDelayed(new Runnable(){

    public void run() {
       popupWindow.showAtLocation(context.getWindow().getDecorView(), Gravity.CENTER,0,0);
    }

}, 200L);
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.