안드로이드 개발

android.view.WindowManager$BadTokenException 해결

피커 2023. 5. 5. 08:34
728x90
반응형

안드로이드 앱을 출시하고 개발자  console에서 아래와 같은 익셉션이 발생했다는 보고를 받았습니다.

android.view.WindowManager$BadTokenException

이를 해결하는 간단한 방법을 소개합니다.

 

1. 에러 로그 (from play console)

Exception android.view.WindowManager$BadTokenException:
  at android.view.ViewRootImpl.setView (ViewRootImpl.java:1249)
  at android.view.WindowManagerGlobal.addView (WindowManagerGlobal.java:404)
  at android.view.WindowManagerImpl.addView (WindowManagerImpl.java:134)
  at android.app.Dialog.show (Dialog.java:363)
  at com.picker.sdbeautypicker.ViewSdImageActivity.onSdApiFailure (ViewSdImageActivity.java:224)
  at com.picker.sdbeautypicker.SdApiHelper$1.lambda$onFailure$0$com-picker-sdbeautypicker-SdApiHelper$1 (SdApiHelper.java:71)
  at com.picker.sdbeautypicker.SdApiHelper$1$$ExternalSyntheticLambda3.run
  at android.os.Handler.handleCallback (Handler.java:938)
  at android.os.Handler.dispatchMessage (Handler.java:99)
  at android.os.Looper.loopOnce (Looper.java:233)
  at android.os.Looper.loop (Looper.java:344)
  at android.app.ActivityThread.main (ActivityThread.java:8212)
  at java.lang.reflect.Method.invoke
  at co m.android.internal.os.RuntimeInit$MethodAndArgsCaller.run (RuntimeInit.java:584)
  at com.android.internal.os.ZygoteInit.main (ZygoteInit.java:1034)

 

2. 에러 코드 

  -.에러가 발생한 지점은 아래 alert.show()입니다.

    특정 상황에서 show()를 부를 경우 문제가 발생하는것으로 보이네요.

    일반적인 상황에서는 문제가 나오지 않았습니다.

AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setMessage("Request Type: " + requestType)
        .setTitle("Call Stable Diffusion API failed")
        .setPositiveButton("OK", (dialog, id) -> ViewSdImageActivity.this.onBackPressed());
AlertDialog alert = builder.create();
alert.show();

 

3. 해결 방법

 -. isFinishing()이라는 api를 쓰게되면 문제는 깔끔히 해결됩니다.

    isFinishing은 activity가 종료중인지 여부를 체크하게 되는데, api 호출시 발생하는 에러 빈도를 확! 낮춰줍니다.

    alert 이나 toast를 사용하실때는 isFinishing을 사용하시기 바랍니다.

if (!isFinishing()) {
    AlertDialog.Builder builder = new AlertDialog.Builder(this);
    builder.setMessage("Request Type: " + requestType)
            .setTitle("Call Stable Diffusion API failed")
            .setPositiveButton("OK", (dialog, id) -> ViewSdImageActivity.this.onBackPressed());
    AlertDialog alert = builder.create();
    alert.show();
}

  -. 간혹 try catch문을 넣어서 익셉션이 나도 넘어가게 만드는 분들이 있습니다.

     당장은 이슈가 해결되겠지만, 추후 디버깅이 안됩니다.

     상용화 코드를 작성해보신 분들이라면 try catch문을 가볍게 적용하지 않습니다.

 

*. isFinishing() 백서

반응형