PopupWindow $ BadTokenException: no se puede agregar la ventana; el token nulo no es válido

80

Tengo el siguiente error al mostrar una ventana emergente. Los errores son provocados por la línea:

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

mapView es un MapView y nada es nulo. El stacktrace:

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)

Este es el código de mi actividad (que extiende 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);
}

Gracias por compartir tus pensamientos

znat
fuente

Respuestas:

71

está mostrando su ventana emergente demasiado pronto. Puede publicar un ejecutable retrasado para mostrar ubicación en Onresume, pruébelo

Editar: Esta publicación parece tener el mismo problema respondido Problemas al crear una ventana emergente en la actividad de Android

nandeesh
fuente
Sugeriría capturar la excepción y seguir publicando con un retraso considerable (al menos algunas veces), ya que no se puede anticipar el retraso inicial.
Duro
93

El mismo problema sucedió conmigo cuando trato de mostrar el menú emergente en la actividad, también obtuve la misma excepción, pero encuentro un problema y lo resuelvo al proporcionar contexto

YourActivityName.this en lugar de getApplicationContext()en

Dialog dialog = new Dialog(getApplicationContext());

y sí, funcionó para mí, puede ayudar a alguien más

Android lo es todo para mi
fuente
Esto me ayudó mucho. Buena respuesta gracias
Tharusha
34

Utilizar:

YourActivityName.this

En vez de:

getApplicationContext();
Mian Taimoor Tahir
fuente
1
Sí, esto funciona para un: new ProgressDialog (YourActivityName.this);
Lotfi
10

Hay dos escenarios en los que podría producirse esta excepción. Uno es mencionado por nandeesh. Otro escenario se menciona aquí: http://blackriver.to/2012/08/android-annoying-exception-unable-to-add-window-is-your-activity-running/

Asegúrate de manejar ambos

El hombre
fuente
7
Tenga en cuenta que no se recomiendan las respuestas de solo enlace, las referencias tienden a quedarse obsoletas con el tiempo. Considere agregar una sinopsis independiente aquí, manteniendo el enlace como referencia.
kleopatra
@TheMan Nice ~ ¡un consejo tan pequeño y poderoso! ¡Gracias!
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);
    }
}

la forma correcta es popupwindow.show () en onWindowFocusChanged ().

Wow Chong
fuente
Esto aborda el problema de la pregunta original y es la mejor y más limpia solución.
Dale
3

El padre de una ventana emergente no puede ser una ventana emergente. Ambos padres deben ser iguales. Por lo tanto, si crea una ventana emergente dentro de una ventana emergente, debe guardar la ventana emergente del padre y convertirla en padre.

aquí hay un ejemplo

Md Kauser Ahmmed
fuente
1

Intenta mostrar el pop como a continuación

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();
                }
            });
        }
    });
Gyanendra Singh
fuente
1

usa este método antes de mostrar

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;
}
Ali Bagheri
fuente
0

Intenta usarlo

LayoutInflater inflater = (LayoutInflater).getApplicationContext().getSystemService(LAYOUT_INFLATER_SERVICE);
View view = inflate.from(YourActivity.this).inflate(R.layout.yourLayout, null);
K.Nikita
fuente
¿Podría publicar el código completo para asegurarse de que está reemplazando el material correcto? Gracias.
kwoxer
0

Después de muchas horas de búsqueda y pruebas, encontré la siguiente solución (mediante la implementación de diferentes soluciones SO) aquí, lo que no falló, en cualquier caso, me estaba bloqueando.

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

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

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

Donde logcat indica que se está produciendo el bloqueo ... inicie un ejecutable .en mi caso al recibir la transmisión.

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

intenta mostrar una ventana emergente como esta

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

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

}, 200L);
Jay Patoliya
fuente