PopupWindow $ BadTokenException:ウィンドウを追加できません—トークンnullは無効です


80

PopupWindowを表示すると、次のエラーが発生します。エラーは次の行によってトリガーされます。

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

mapViewはMapViewであり、nullはありません。スタックトレース:

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でshowatlocationの遅延ランナブルを投稿できます。試してみてください

編集: この投稿には、Androidアクティビティでポップアップウィンドウを作成する際の問題に答えた同じ問題があるようです


最初の遅延は予測できないため、例外をキャッチし、かなりの遅延(少なくとも数回)で再投稿を続けることをお勧めします。
厳しい

93

アクティビティでポップアップメニューを表示しようとすると同じ問題が発生しましたが、同じ例外が発生しましたが、コンテキストを提供することで問題を解決できます

YourActivityName.this 代わりのgetApplicationContext()

Dialog dialog = new Dialog(getApplicationContext());

はい、それは私のために働きましたそれは他の誰かを助けるかもしれません


これは私をよく助けました。良い答え
ありがとう

34

使用する:

YourActivityName.this

の代わりに:

getApplicationContext();

1
はい、これは次の場合に機能します:new ProgressDialog(YourActivityName.this);
ロトフィ

10

この例外が発生する可能性があるシナリオは2つあります。1つはnandeeshによって言及されています。他のシナリオはここで言及されています:http//blackriver.to/2012/08/android-annoying-exception-unable-to-add-window-is-your-activity-running/

必ず両方を処理してください


7
リンクのみの回答は推奨されておらず、参照は時間の経過とともに古くなる傾向があることに注意してください。リンクを参照として保持しながら、ここにスタンドアロンの概要を追加することを検討してください。
kleopatra 2013年

@TheMan Nice〜とても小さな強力なヒント!ありがとうございました!
cmcromance 2013

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

正しい方法は、onWindowFocusChanged()のpopupwindow.show()です。


これは元の質問の問題に対処し、最良/最もクリーンな解決策です。
デール

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 2017

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);
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.