ViewCompositionStrategy 알아보기

강현석·2023년 5월 28일
1

article

목록 보기
8/10
post-custom-banner

본 글은 학습을 위해 ViewCompositionStrategy Demystified를 읽고 입맛대로 정리하였습니다.


Composition

  • composable을 실행하여 생성됨
  • composition이 더이상 필요하지 않으면?
    • state를 트래킹하지 않음
    • 리소스를 해제할 수 있도록 composition 삭제

ViewCompositionStrategy

  • composition을 dispose해야하는 시기를 정의함
  • ViewCompositionStrategy.Default는 ComposeView가 window에서 분리될 때 composition 삭제

Composition disposing

  • composition이 dispose되면 리소스는 정리되고 state는 Compose에 의해 더이상 트래킹되지 않음
  • 적용된 특정 strategy는 composition이 자동으로 dispose되는 시기를 결정함
  • 기본적으로는 대부분 strategy를 설정할 필요는 없음
  • setViewCompositionStrategy 를 통해 다른 strategy를 적용할 수 있음
    val composeView = ComposeView(context = context)
    composeView.setViewCompositionStrategy(
        ViewCompositionStrategy.DisposeOnViewTreeLifecycleDestroyed
    )

type

DisposeOnDetachedFromWindow

  • ComposeView가 Window에서 detach됐을 때 Composition이 dispose됨
    • View가 screen에서 벗어나서 사용자에게 더이상 표시가 되지 않을 때
      • ViewGroup.removeView* 를 통해 View가 제거됐을 때
      • View가 Transition의 일부일 때
      • Activity가 destroy됐을 때 (onStop 이후, onDestroy 이전)

DisposeOnDetachedFromWindowOrReleasedFromPool

  • ComposeView가 RecyclerView와 같은 pooling container 내에서 사용될 때
  • UI가 스크롤로 재활용됨에 따라 view element가 window에 attach 또는 re-attach될 때 dispose됨
  • Composition을 자주 dispose하고 재생성하면 스크롤 성능이 저하될 수 있는 부분을 개선

DisposeOnLifecycleDestroyed

  • 설정된 Lifecycle이 destroy됐을 때 dispose됨
  • ComposeView가 lifecycle과 일대일관계일 때 적합함
  • Fragment의 View에서 사용하기 적합함
    • View는 detach되었으나, Fragment가 destroy되지 않을 수 있음
      class MyFragment : Fragment() {
          // …
          override fun onCreateView(
              inflater: LayoutInflater,
              container: ViewGroup?,
              savedInstanceState: Bundle?
          ) = ComposeView(requireContext()).apply {
              setViewCompositionStrategy(
                  ViewCompositionStrategy.DisposeOnLifecycleDestroyed(
                      lifecycle = this@MyFragment.lifecycle // <== Lifecycle 지정
                  )
              )
              // …
          }
      }

만약 Fragment 내에 RecyclerView가 있고, RecyclerView의 item에 ComposeView가 있다면?

  • DisposeOnDetachedFromWindowOrReleasedFromPool 사용
    • ComposeView는 RecyclerView의 item이기 때문
    • 그렇지 않은 경우, DisposeOnLifecycleDestroyed 사용

DisposeOnViewTreeLifecycleDestroyed

  • View가 attach된 다음 window의 ViewTreeLifecycleOwner가 destroy될 때 dispose됨

  • Fragment View와 같이 ViewTreeLifecycleOwner와 일대일 관계일 때 적합

    class MyCustomView @JvmOverloads constructor(
        context: Context,
        attrs: AttributeSet? = null,
        defStyle: Int = 0
    ) : AbstractComposeView(context, attrs, defStyle) {
    
        init { // <== 이 시점에는 관련 lifecycle을 알지 못함
        	setViewCompositionStrategy(
          		ViewCompositionStrategy.DisposeOnViewTreeLifecycleDestroyed
        	)
      	}
    
        @Composable
        override fun Content() {
          // Compose
        }
    }

언제 DisposeOnViewTreeLifecycleDestroyed 사용해야할까?

  • Lifecycle을 모를 경우
profile
볼링을 좋아하는 안드로이드 개발자
post-custom-banner

1개의 댓글

comment-user-thumbnail
2023년 11월 1일

좋은 글 감사합니다~

답글 달기