이따금식 LifecycleOnwer 를 사용하기 위해, View 의 확장함수인 findViewTreeLifecycleOwner 를 사용하는 경우가 있습니다.
간혹 아무 생각 없이 사용하다보면 findViewTreeLifecycleOwner 가 null 을 반환하는 경우가 있습니다.
RecyclerView 에서 사용하는 케이스는 https://pluu.github.io/blog/android/2021/09/20/lifecycleowner/ 에서 잘 설명하고 있어서 해당 글을 참고 해도 좋을 것 같습니다.
RecyclerView 에서는 doOnAttach 함수를 사용하여, Lifecycle 을 얻어올 수 있지만, doOnAttach 로 해결되지 않는 케이스들도 존재 합니다.
먼저 ViewTreeLifecycleOwner.get(this) 함수의 구현체를 보면
while 문을 돌면서 부모 뷰를 찾고 부모 뷰에서 R.id.view_tree_lifecycle_owner 로 저장된 Tag 가 있는지 확인하여 해당 뷰에 set 되어 있는 LifecycleOwner 를 사용하게 되는 원리 입니다.
결국 타고 타고 올라가다 보면, 대부분 상황은 (Component)Activity, Fragment, DialogFragment 와 마주할 것이고, 각 클래스들은 LifecycleOwner 의 구현체(implement)를 가지고 있고 생성될 때 LifecycleOwner set 되고 있습니다.
그럼 어떤 상황이면 findViewTreeLifecycleOwner 가 null 을 반환될 수 있을지 생각해보면, 타고 타고 올라갔을 때, Activity, DialogFragment, Fragment 같이 Lifecycle 의 구현체를 가지고 있지 않고, set 해주지 않는 곳이면 모두 발생하게 됩니다.
가령 대표적인 경우가 Dialog, PopupWindow 등의 경우 입니다.
Lifecycle 의 구현체를 가지지 않기 때문에 항상 null 일수 밖에 없습니다.
따라서
ViewTreeLifecycleOwner.set(decorView /* 부모 뷰 */, lifecycle or viewLifecycle)
위와 같이 Dialog, PopupWindow 컨텐츠 영역 중 부모 뷰에 사용하고 싶은 Activity 의 lifecycle 이나 Fragment 의 lifecycle 혹은 viewLifecycle 등을 넣어주게 되면, 위에서 이야기한 것 처럼 while 문을 통해 부모에 있는 lifecycle 를 가져와서 사용할 수 있게 됩니다.
간단한 내용을 괜시리 길게 쓴 것 같은 느낌이네요.
중요한 점은, 뷰가 window 에 붙어 있는 상황과 상관 없이 부모중에 lifecycle 구현체를 가지고 있지 언제든 findViewTreeLifecycleOwner 가 null 이 될 수 있다는 점입니다.
Compose 에서는
CompositionLocalProvider(
LocalLifecycleOwner provides this,
)
val LocalLifecycleOwner = staticCompositionLocalOf<LifecycleOwner> {
noLocalProvidedFor("LocalLifecycleOwner")
}
와 같은 방식을 사용하여 좀더 쉽게 처리할 수 있습니다.
그럼 20000
'Android > Today I Learned' 카테고리의 다른 글
Coil 사용하는데, Disk Hit 이 되지 않는다 ?! (feat. Glide) (0) | 2024.08.05 |
---|---|
네트워크 요청 실패했는데, RunCatching onSuccess 가 호출? (0) | 2022.06.23 |
주관적인 Compose 사용 후기 (4) | 2022.06.11 |
서버 디펜던시 없이 네트워크 작업 캐시 구현하기(feat.OkHttp) (0) | 2022.04.06 |
Material library 1.5.0 로 올리니 크래시가?! (1) | 2022.03.11 |