Activity has leaked window 문제 수정하기
Stack Overflow에 자주 검색, 등록되는 문제들과 제가 개발 중 찾아 본 문제들 중에서 나중에도 찾아 볼 것 같은 문제들을 정리하고 있습니다.
Stack Overflow에서 가장 먼저 확인하게 되는 가장 높은 점수를 받은 Solution과 현 시점에 도움이 될 수 있는 가장 최근에 업데이트(최소 점수 확보)된 Solution을 각각 정리하였습니다.
아래 word cloud를 통해 이번 포스팅의 주요 키워드를 미리 확인하세요.
Activity has leaked window that was originally added
Activity has leaked window 문제 수정하기
문제 내용
What is this error, and why does it happen?
이 오류는 무엇이며, 왜 발생합니까?
05-17 18:24:57.069: ERROR/WindowManager(18850): Activity com.mypkg.myP has leaked window com.android.internal.policy.impl.PhoneWindow$DecorView@44c46ff0 that was originally added here
05-17 18:24:57.069: ERROR/WindowManager(18850): android.view.WindowLeaked: Activity ccom.mypkg.myP has leaked window com.android.internal.policy.impl.PhoneWindow$DecorView@44c46ff0 that was originally added here
05-17 18:24:57.069: ERROR/WindowManager(18850): at android.view.ViewRoot.<init>(ViewRoot.java:231)
05-17 18:24:57.069: ERROR/WindowManager(18850): at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:148)
05-17 18:24:57.069: ERROR/WindowManager(18850): at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:91)
05-17 18:24:57.069: ERROR/WindowManager(18850): at android.view.Window$LocalWindowManager.addView(Window.java:424)
05-17 18:24:57.069: ERROR/WindowManager(18850): at android.app.Dialog.show(Dialog.java:239)
05-17 18:24:57.069: ERROR/WindowManager(18850): at com.mypkg.myP$PreparePairingLinkageData.onPreExecute(viewP.java:183)
05-17 18:24:57.069: ERROR/WindowManager(18850): at android.os.AsyncTask.execute(AsyncTask.java:391)
05-17 18:24:57.069: ERROR/WindowManager(18850): at com.mypkg.myP.onCreate(viewP.java:94)
05-17 18:24:57.069: ERROR/WindowManager(18850): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1047)
05-17 18:24:57.069: ERROR/WindowManager(18850): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2544)
05-17 18:24:57.069: ERROR/WindowManager(18850): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2621)
05-17 18:24:57.069: ERROR/WindowManager(18850): at android.app.ActivityThread.access$2200(ActivityThread.java:126)
05-17 18:24:57.069: ERROR/WindowManager(18850): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1932)
05-17 18:24:57.069: ERROR/WindowManager(18850): at android.os.Handler.dispatchMessage(Handler.java:99)
05-17 18:24:57.069: ERROR/WindowManager(18850): at android.os.Looper.loop(Looper.java:123)
05-17 18:24:57.069: ERROR/WindowManager(18850): at android.app.ActivityThread.main(ActivityThread.java:4595)
05-17 18:24:57.069: ERROR/WindowManager(18850): at java.lang.reflect.Method.invokeNative(Native Method)
05-17 18:24:57.069: ERROR/WindowManager(18850): at java.lang.reflect.Method.invoke(Method.java:521)
05-17 18:24:57.069: ERROR/WindowManager(18850): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:860)
05-17 18:24:57.069: ERROR/WindowManager(18850): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:618)
05-17 18:24:57.069: ERROR/WindowManager(18850): at dalvik.system.NativeStart.main(Native Method)
높은 점수를 받은 Solution
You're trying to show a Dialog after you've exited an Activity.
액티비티를 종료한 후 대화상자를 표시하려고 합니다.
[EDIT]
[편집]
This question is one of the top search on google for android developer, therefore Adding few important points from comments, which might be more helpful for future investigator without going in depth of comment conversation.
이 질문은 Android 개발자를 위한 Google의 상위 검색 중 하나이므로 댓글에서 몇 가지 중요한 사항을 추가하면 댓글 대화에 깊이 들어가지 않고도 향후 조사자에게 더 도움이 될 수 있습니다.
Answer 1 :
정답 1:
You're trying to show a Dialog after you've exited an Activity.
활동을 종료한 후 대화상자를 표시하려고 합니다.
Answer 2
정답 2
This error can be a little misleading in some circumstances (although the answer is still completely accurate) - i.e. in my case an unhandled Exception was thrown in an AsyncTask, which caused the Activity to shutdown, then an open progressdialog caused this Exception.. so the 'real' exception was a little earlier in the log
이 오류는 일부 상황에서 약간 오해의 소지가 있을 수 있습니다(대답은 여전히 완전히 정확하지만). 즉, 제 경우에는 AsyncTask에서 처리되지 않은 예외가 발생하여 활동이 종료된 다음 열린 진행 대화 상자로 인해 이 예외가 발생했습니다. '실제' 예외는 로그에서 조금 더 일찍 발생했습니다.
Answer 3
정답 3
Call dismiss() on the Dialog instance you created before exiting your Activity, e.g. in onPause() or onDestroy()
Activity를 종료하기 전에 생성한 Dialog 인스턴스에 대해 onPause() 또는 onDestroy()에서 disable()을 호출합니다.
가장 최근 달린 Solution
here is a solution when you do want to dismiss AlertDialog but do not want to keep a reference to it inside activity.
다음은 AlertDialog를 닫고 싶지만 Activity 내부에 대한 참조를 유지하고 싶지 않은 경우의 솔루션입니다.
solution requires you to have androidx.lifecycle dependency in your project (i believe at the moment of the comment it's a common requirement)
솔루션을 사용하려면 프로젝트에 androidx.lifecycle 종속성이 있어야 합니다.
this lets you to delegate dialog's dismiss to external object (observer), and you dont need to care about it anymore, because it's auto-unsubscribed when activity dies. (here is proof: https://github.com/googlecodelabs/android-lifecycles/issues/5).
이를 통해 다이얼로그 닫기를 외부 객체(관찰자)에게 위임할 수 있으며 액티비티가 종료되면 자동으로 구독 취소되기 때문에 더 이상 신경 쓸 필요가 없습니다. (증거: https://github.com/googlecodelabs/android-lifecycles/issues/5).
so, the observer keeps the reference to dialog, and activity keeps reference to observer. when "onPause" happens - observer dismisses the dialog, and when "onDestroy" happens - activity removes observer, so no leak happens (well, at least i dont see error in logcat anymore)
따라서 옵저버는 다이얼로그에 대한 참조를 유지하고 액티비티는 옵저버에 대한 참조를 유지합니다. "onPause"가 발생하면 옵저버가 다이얼로그를 닫고 "onDestroy"가 발생하면 액티비티가 옵저버를 제거하므로 누출이 발생하지 않습니다(적어도 logcat에는 더 이상 오류가 표시되지 않습니다)
// observer
class DialogDismissLifecycleObserver( private var dialog: AlertDialog? ) : LifecycleObserver {
@OnLifecycleEvent(Lifecycle.Event.ON_PAUSE)
fun onPause() {
dialog?.dismiss()
dialog = null
}
}
// activity code
private fun showDialog() {
if( isDestroyed || isFinishing ) return
val dialog = AlertDialog
.Builder(this, R.style.DialogTheme)
// dialog setup skipped
.create()
lifecycle.addObserver( DialogDismissLifecycleObserver( dialog ) )
dialog.show()
}
출처 : https://stackoverflow.com/questions/2850573/activity-has-leaked-window-that-was-originally-added