[Compose] 언제 composition을 제거해야 할까?
🔗 들어가며
fragment 화면을 compose로 구성 또는 ComposeView을 활용할 setContent 안에 해당 코드를 넣은 기억이 있을 것이다.
setViewCompositionStrategy(ViewCompositionStrategy.DisposeOnViewTreeLifecycleDestroyed)
그렇다면 이 코드의 역할은 무엇일까? 말 그래도
🔗 ViewCompositionStrategy 종류
DisposeOnDetachedFromWindow
DisposeOnDetachedFromWindowOrReleasedFromPool (default)
DisposeOnLifecycleDestroyed
DisposeOnViewTreeLifecycleDestroyed
우선 다음의 4가지 전략이 있다. 그렇다면 각 전략을 언제 활용해야 하는지에 대해 자세히 살펴보자!
🔗 1. DisposeOnDetachedFromWindow
- activity는 window에 attach될 때 그려진다.
- compose를 activity에서 활용하거나
ViewGroup.removeView..
가 진행될 때 트리거 된다. - 즉, window에서 detached될 때 composition을 제거한다.
- 현재, DisposeOnDetachedFromWindowOrReleasedFromPool로 대체되었다.
🔗 2. DisposeOnDetachedFromWindowOrReleasedFromPool (default)
- compose가 recyclerView과 같이 pooling container 안에서 존재할 때
- recyclerview 안에 compose가 존재할 때 DisposeOnDetachedFromWindow를 사용한다면 스크롤 중 각 아이템에 대해 dispose + recreate가 빈번하게 발생해 성능 이슈가 발생할 수 있다!
- 해당 전략을 사용할 경우, pooling container 자체가 창에서 분리되거나 삭제될 때 composition이 제거된다.
[권장되는 사용 시기]
- ComposeView whether it’s the sole element in the View hierarchy, or in the context of a mixed View/Compose screen (not in Fragment).
- view 계층에서 ComposeView 하나만이 존재하는 경우
- fragment가 아닌 상태에서 View/Compose가 섞인 화면 속에서 사용될 경우
- ComposeView as an item in a pooling container such as RecyclerView.
- recyclerView 안 item의 경우
🔗 3. DisposeOnLifecycleDestroyed
- 인자로 전달받은 lifecycle이 destroy될 때 composition도 해제된다.
- fragment 환경의 composeView에서 쓰기 용이하다.
- view는 detached 되었으나 fragment가 destroy되지 않는 경우가 존재하기 때문이다.
- ComposeView가 lifecycle과 1:1 관계일 때 적합하다.
[권장 사용 시기]
- ComposeView in a Fragment’s View.
fragment 안
에서 ComposeView를 사용할 경우
🔗 4. DisposeOnViewTreeLifecycleDestroyed
- view가 attach된 이후 현재의 window의 viewTreeLifecycleOwner가 destroy될 때 composition이 해제된다.
- composeView를 사용하는 부분에서
lifecycle을 모를 때 사용하면 된다.</span>
[권장 사용 시기]
- ComposeView in Fragment’s View.
fragment 안
에서 ComposeView를 사용할 경우- ComposeView in a View wherein the Lifecycle is not known yet.
- lifecycle을 잘 모르는 View 속 ComposeView를 사용할 경우
🔗 5. ComposeView in Fragment 상황에서는 어떤 전략을 사용해야 하지??
-
composition는 보통 composeView가 window에서 detached될 때 dispose된다.
-
fragment에서 ComposeView를 사용할 경우, 해당 전략이 적절하지 않은 이유
- fragment View의 생명주기와 일치해야 한다.
- compose ui가 state를 저장하기 위해 composition이
fragment의 view의 lifecycle
을 따라야 한다. - 특히, Compose의 Ui 상태를 저장해야 하는 경우, fragment 생명주기와 맞춰져야 한다.
- compose ui가 state를 저장하기 위해 composition이
- trasition(화면 전환) 중 상태 유지를 해야 한다.
- 화면 전환 상태에서 ComposeView가 잠깐 분리되는 순간이 존재한다. 이때 화면에서 분리되었다고 해서 Composition이 해제되면, 중간에 갑자기 UI가 사라지는 문제가 발생할 수 있다.
- UI는 화면 전환 과정에서도 계속 보여야 한다.
- fragment View의 생명주기와 일치해야 한다.
🤔 그렇다면 DisposeOnLifecycleDestroyed
를 사용해도 되지 않을까??
Fragment에는 lifecycle이 크게 두 가지가 존재한다.
- fragment 자체의 lifecycle
- fragment의
view
의 lifecycle
위 두 전략을 비교해본다면 다음과 같다.
-
DisposeOnLifecycleDestroyed
fragment 자체 lifecycle이 소멸될 때 composition이 해제된다. 하지만 fragment view와 fragment의 생명주기는 서로 다르다. 따라서 뷰가 파괴된 상태에서도 composition이 해제되지 않아 메모리 누수나 상태 불일치가 발생할 수 있다.
-
DisposeOnViewTreeLifecycleDestroyed
fragment의 view의 생명주기에 맞춰 composition이 관리되기 때문에 fragment 전환이나 애니메이션 도중 UI가 안전하게 유지될 수 있다.
댓글남기기