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

그리고 네 그것은 나를 위해 일했습니다 다른 사람을 도울 수 있습니다


이것은 나를 잘 도왔습니다. 좋은 답변 고맙습니다
Tharusha


10

이 예외가 발생할 수있는 두 가지 시나리오가 있습니다. 하나는 nandeesh가 언급합니다. 다른 시나리오는 http://blackriver.to/2012/08/android-annoying-exception-unable-to-add-window-is-your-activity-running/에서 언급됩니다.

둘 다 처리해야합니다.


7
링크 전용 답변은 권장하지 않으며 참조는 시간이 지남에 따라 부실 해지는 경향이 있습니다. 링크를 참조로 유지하면서 여기에 독립형 시놉시스를 추가하는 것을 고려하십시오.
클레오 파트라

@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 ()입니다.


이것은 원래 질문의 문제를 해결하며 최상의 / 가장 깨끗한 솔루션입니다.
Dale

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이 크래시가 발생하고 있음을 나타내는 곳입니다. 제 경우에는 브로드 캐스트를 수신 할 때 runnable.

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.