Android

[android] Dialog 오류 (WindowLeaked… that was originally added )원인을 드디어 밝혀냈다. 해결책은???

거의 2년 넘게 계속해서 지속적으로 발생된 오류가 하나 있다. 원인을 찾을 수 없었고, 구글링을 통하여 로직을 수정해가며 처리를 하였음에도 동일한 오류는 지속되었다. 그 오류는 다음과 같다. WindowLeaked… that was originally added here… 이 오류가 발생하는 원인은 다이알로그 뜬 상태에서 액티비티를 종료시킨 경우에 발생한다.

2020-06-25 16:58:43.536 18576-18576/com.test E/WindowManager: android.view.WindowLeaked: Activity com.test.MainActivity has leaked window DecorView@c7f48b3[MainActivity] that was originally added here
        at android.view.ViewRootImpl.<init>(ViewRootImpl.java:625)
        at android.view.WindowManagerGlobal.addView(WindowManagerGlobal.java:403)
        at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:102)
        at android.app.Dialog.show(Dialog.java:416)
        at com.test.MainActivity.callNotiDialog(MainActivity.java:1674)
        at com.test.MainActivity$14.run(MainActivity.java:1636)
        at android.os.Handler.handleCallback(Handler.java:883)
        at android.os.Handler.dispatchMessage(Handler.java:100)
        at android.os.Looper.loop(Looper.java:214)
        at android.app.ActivityThread.main(ActivityThread.java:7615)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:492)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:964)

 

■오류가 발생한 코드

public void callNotiDialog(){ 
  try {
	if (!MainActivity.this.isFinishing()) { 
    
		final Dialog customDialog2 = new Dialog(MainActivity.this);
		customDialog2.requestWindowFeature(Window.FEATURE_NO_TITLE);
		customDialog2.setContentView(R.layout.dialog_charge_complete);
		customDialog2.getWindow().setBackgroundDrawable(new ColorDrawable(0));    
		customDialog2.setCanceledOnTouchOutside(false);
		customDialog2.setCancelable(false); 
		TextView txtRingtone = customDialog2.findViewById(R.id.musicTxt);
		txtRingtone.setText(getRingToneName());

		if (!MainActivity.this.isFinishing() && customDialog2 != null && !customDialog2.isShowing()) {
			customDialog2.show();
		}

		LinearLayout linearLayout4 = customDialog2.findViewById(R.id.linearLayout4);
		linearLayout4.setOnClickListener(new View.OnClickListener() {
			@Override
			public void onClick(View v) {
				if (v.getId() == R.id.linearLayout4) {
					if (!MainActivity.this.isFinishing() && customDialog2 != null && customDialog2.isShowing()) {
						customDialog2.dismiss();
						stopVibrate();
					}
				}
			}
		});

	}
  }catch (Exception e){
	e.printStackTrace();
  }
}
 

오류 해결 법을 검색해보면, .isFinishing()메소드를 다이얼로그를 호출하기전에 확인해라는 정보가 굉장히 많다. 하지만 이것도 해결방법은 못되었다.  또다른 해결방법으로 dialog.isShowing() 메소드를 체크 후 다이얼로그 창을 띄우라는 것이었지만, 이것 역시 효과는 보지 못했다. 원인을 찾기 위해 삽질은 시작되었다.  혹시나 하는 마음에 딜레이를 주기위해  Handler도 사용해보았다. 핸드러를 사용하여 2초 후 다이얼로그 로직을 호출하도록 처리해보았다.

        Handler handler = new Handler();
        handler.postDelayed(new Runnable() {
            public void run() {
                callNotiDialog();
            }
        }, 2000);  //2초
        
        
        //역시 실패!!
        runOnUiThread(new Runnable(){
            @Override
            public void run() {
                callNotiDialog();
            }
        });

그러나 이 역시 해결법이 못되었다. 그렇다면 딜레이를 줘볼까 해서 스레드도 사용하였다.

try {
	 Thread.sleep(3000);
}catch (InterruptedException e){

}
 callNotiDialog();

화면이 하얀색 상태에서 딜레이를 준 3초 후에야 앱의 화면이 나타나는 문제점이 생겼다. 이것도 해결책이 아니였다. 원인도 모르는 상태에서 해결책을 계속 찾아야만 했다. 왜 오류가 발생하였는가? 역시 알 수 없었기 때문에 삽질은 끝없이 되었고…..

우연히 원인을 찾았다. 휴대폰 화면이 잠금화면일 경우 혹은 화면이 꺼져있는 경우 문제가 발생하였다. 휴대폰 화면이 잠금화면이 아닌경우 정상적으로 동작하였다.  잠금화면상태에서 앱을 실행되었고, 이상태에서 잠금화면을 해제해서 실행된 앱을 보면 먹통이 되어있었다. 혹은 다이얼로그창을 띄웠을 때 배경이 흐려지는 효과까지 나타나있었지만 다이얼로그창을 보이지않았다. 이상태에서 앱을 강제 종료시키면 위에서 발생한 오류가 동일하게 발생함을 확인하였다. 다이얼로그가 뜬 상태에서 앱을 종료시켜서 발생하는 오류인 것이다. 그렇다면 사용자들도 앱이 멈췄고, 버튼도 눌리지 않았으니 앱을 강제 종료했을 확률이 높아졌다.  앱이 멈췄으니 다이얼로그 창도 보이지않고 다이얼로그 창을 종료할 방법이 없는 것이다. 좀 더 자세히 들어가보면 앱은 이미 실행되어 화면에 나타났지만, 다이얼로그창을 호출하지 못한 상태에서 앱은 동작을 멈추었고, 이상태에서 앱을 강제종료하면 customDialog2.show(); 부분에서 오류가 발생하는 것이다.

 

자 그럼 해결책은???????????????????????????? 해결책은 간단하다. 다이얼로그 선언을 전역변수로 선언 후 앱이 종료될때 onDestory()가 호출될 때 .dismiss()를 호출해주면 해결될 일이다. 이것은 사용자에게 보이지않는 오류이며, 사용자는 알지도 못한다.  그렇다면 앱은 실행되었는데, 왜 다이얼로그를 호출하지 못한 상태가 되는가?????????

 

이제 부터가 시작이다.!!!  중요한 것은 오류가 아니라, 화면이 잠금상태일때 다이얼로그 창이 보이지 않는다는 것이며, 앱을 사용할 수 없는 상태에 빠진다는 데에 있다. 다이얼로그창을 버리고 토스트 메세나 스낵바를 써볼까????

 

 

[관련글]

https://stackoverflow.com/questions/41717561/activity-has-leaked-window-that-was-originally-added-here

https://www.youtube.com/watch?v=0LwzAg-K6Rw

https://stackoverflow.com/questions/2850573/activity-has-leaked-window-that-was-originally-added

https://stackoverflow.com/questions/19074466/android-how-to-show-dialog-or-activity-over-lock-screen-not-unlock-the-screen

 

 

Leave a Reply

error: Content is protected !!