PopupWindow $ BadTokenException: Fenster kann nicht hinzugefügt werden - Token null ist ungültig

80

Ich habe den folgenden Fehler beim Anzeigen eines PopupWindow. Die Fehler werden durch die Zeile ausgelöst:

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

mapView ist eine MapView und nichts ist null. Die Stapelspur:

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)

Dies ist der Code aus meiner Aktivität (der MapActivity erweitert)

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

Vielen Dank für Ihre Meinung

znat
quelle

Antworten:

71

Sie zeigen Ihr Popup zu früh. Sie können eine verzögerte Runnable für die Showlokalisierung in Onresume veröffentlichen. Probieren Sie es aus

Bearbeiten: In diesem Beitrag scheint das gleiche Problem beantwortet worden zu sein. Probleme beim Erstellen eines Popup-Fensters in Android-Aktivitäten

Nandeesh
quelle
Ich würde vorschlagen, die Ausnahme abzufangen und mit einer erheblichen Verzögerung (zumindest einige Male) weiter zu veröffentlichen, da die anfängliche Verzögerung nicht vorhersehbar ist.
Harter
92

Das gleiche Problem trat bei mir auf, als ich versuchte, das Popup-Menü in der Aktivität anzuzeigen. Ich habe auch die gleiche Ausnahme, aber ich stoße auf ein Problem, das durch die Bereitstellung des Kontexts gelöst werden kann

YourActivityName.this statt getApplicationContext()um

Dialog dialog = new Dialog(getApplicationContext());

und ja, es hat bei mir funktioniert, vielleicht hilft es jemand anderem

Android ist alles für mich
quelle
Das hat mir gut geholfen. Gute Antwort Danke
Tharusha
34

Verwenden:

YourActivityName.this

Anstatt:

getApplicationContext();
Mian Taimoor Tahir
quelle
1
Ja, dies funktioniert für: new ProgressDialog (YourActivityName.this);
Lotfi
10

Es gibt zwei Szenarien, in denen diese Ausnahme auftreten kann. Einer wird von Nandeesh erwähnt. Ein anderes Szenario wird hier erwähnt: http://blackriver.to/2012/08/android-annoying-exception-unable-to-add-window-is-your-activity-running/

Stellen Sie sicher, dass Sie beide behandeln

Der Mann
quelle
7
Beachten Sie, dass von Antworten nur mit Links abgeraten wird und Referenzen im Laufe der Zeit veralten. Bitte fügen Sie hier eine eigenständige Zusammenfassung hinzu, wobei Sie den Link als Referenz behalten.
Kleopatra
@ TheMan Nice ~ ein so kleiner, kraftvoller Tipp! Vielen Dank!
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);
    }
}

Der richtige Weg ist popupwindow.show () bei onWindowFocusChanged ().

Wow Chong
quelle
Dies adressiert das Problem der ursprünglichen Frage und ist die beste / sauberste Lösung.
Dale
Das ist die richtige Lösung!
Somerandomusername
3

Das Elternteil eines Popups kann selbst kein Popup sein. Beide Eltern müssen gleich sein. Wenn Sie also ein Popup in einem Popup erstellen, müssen Sie das Popup des übergeordneten Elements speichern und zu einem übergeordneten Element machen.

Hier ist ein Beispiel

Md Kauser Ahmmed
quelle
1

Versuchen Sie, den Pop wie unten zu zeigen

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
quelle
1

Verwenden Sie diese Methode vor der Show

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
quelle
0

Versuche es zu benutzen

LayoutInflater inflater = (LayoutInflater).getApplicationContext().getSystemService(LAYOUT_INFLATER_SERVICE);
View view = inflate.from(YourActivity.this).inflate(R.layout.yourLayout, null);
K. Nikita
quelle
Könnten Sie vielleicht auch den vollständigen Code posten, um sicherzustellen, dass er das richtige Material ersetzt? Vielen Dank.
Kwoxer
0

Nach vielen Stunden des Suchens und Testens fand ich folgende Lösung (durch Implementierung verschiedener SO-Lösungen) hier, was auf keinen Fall fehlschlug, ich bekam einen Absturz.

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

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

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

Wenn logcat anzeigt, dass der Absturz stattfindet, starten Sie in meinem Fall eine ausführbare Datei, wenn Sie eine Sendung empfangen.

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

Versuchen Sie, Popup wie folgt anzuzeigen

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

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

}, 200L);
Jay Patoliya
quelle