[Android] collectAsStateWithLifecycle를 이용하여 라이프사이클에 맞게 Flow 수집해보자!(feat. jetpack Compose)

지난 글에  CoroutineScope에 따라 생명주기에 따라 맞추어 사용하는 방법에 대해 

알아보았는데요, 이번에는 Jetpack Compose에서 라이프사이클에 맞게

Flow를 수집하는 방법에 대해 알아보려고 합니다!


 

1. collectAsStateWithLifecycle 세팅하기

dependencies {
    implementation "androidx.lifecycle:lifecycle-runtime-compose:2.6.0-alpha01"
}

프로젝트에서 사용하기 위해서는 androidx.lifecycle.lifecycle-runtime-compose 아티팩트를 추가해야 합니다.

또한, 아직 알파 단계 API이기 때문에 사용 시, ExperimentalLifecycleComposeApi 어노테이션을 추가해야 합니다.

 

 

 

2. collectAsStateWithLifecycle란

collectAsStateWithLifecycle은 comosable 함수로 flow에서 값을 수집하고 라이프사이클을 인식하여 최신 값을 compose state

나타냅니다. collectAsStateWithLifecycle를 사용하면 앱이 백그라운드에 있어 사용하지 않을 때 불필요한 리소스 낭비를 방지할 수 있습니다. 

 

collectAsStateWithLifecycle은 새로운 flow가 방출할 때마다 state객체의 값이 업데이트되며 State.value가 사용되는 부분에서 recomposition이 일어납니다. 내부 구조를 참고하며 함께 살펴보도록 하겠습니다!

@ExperimentalLifecycleComposeApi
@Composable
fun <T> StateFlow<T>.collectAsStateWithLifecycle(
    lifecycleOwner: LifecycleOwner = LocalLifecycleOwner.current,
    minActiveState: Lifecycle.State = Lifecycle.State.STARTED,
    context: CoroutineContext = EmptyCoroutineContext
): State<T> = collectAsStateWithLifecycle(
    initialValue = this.value,
    lifecycle = lifecycleOwner.lifecycle,
    minActiveState = minActiveState,
    context = context
)

minActiveState를 살펴보면, collectAsStateWithLifecycle은 기본적으로 Lifecycle.State.STARTED를 사용하여 flow에서 값을 수집하거나 중지합니다. minActiveState이기 때문에, 해당 파라미터를 통해 상태 범위를 조절할 수 있습니다.

 

 

위 사진은 라이프사이클에 맞추어 collectAsState와 collectAsStateWithLifecycle를 비교한 것입니다.

collectAsStateWithLifecycle를 먼저 살펴보면, 앱이 백그라운드로 진입했을 때 flow 수집을 멈추고 다시 포그라운드로 

돌아왔을 때 재개하는 것을 확인할 수 있습니다. 반면 collectAsState는 백그라운드로 진입하여도 수집 작업이 활성화된 상태이며, 라이프 사이클이 타겟 상태가 바깥으로 변경될 경우 문제가 발생할 수 있습니다.

 

 

그렇다면 collectAsState는 왜 사용할까? 라는 고민이 생길 수 있습니다!

 

 

3. collectAsState

collectAsState는 Composition의 라이프사이클을 따르고, composable이 Composition 단계에 진입할 때 flow를 수집하기 시작합니다. collectAsState는 Android앱이 백그라운드에 있는 동안 recomposition을 중지하더라고 수집 작업이 활성화된 상태로 유지하기 때문에 나머지 레이어에 대한 리소스를 확보할 수 없으며, collectAsState는 flow를 수집하는데 플랫폼에 구애받지 않는 API라고 합니다.  

 

하지만 Android앱에서 라이프사이클은 리소스를 관리하는 방법에서 중요한 역할을 맡고 있기 때문에 앱이 백그라운드에 있는 동안 flow 수집 활동을 중지할 수 있는 collectAsStateWithLifecycle를 사용한다면, 안전하고 불필요한 리소스 낭비를 방지할 수 있다고 합니다.

두 가지 API 모두 Compose에서 사용하지만, collectAsStateWithLifecycle은 Android 앱을 개발할 때, collectAsState는 다른 플랫폼을 위해 개발할 때 사용하는 것이 좋다고 합니다.

 

 

 

*collectAsStateWithLifecycle를 사용하는 예제는 아래 참고 링크에 첨부된 Android Developers에서 자세하게 확인해 볼 수 있습니다!!

 

 

마무리

최근 컴포즈 클론 코딩을 시작하면서 새로운 것을 많이 알게 되고 공부할 내용들이 많다는 것을 알게 되었습니다. collectAsStateWithLifecycle도 클론 코딩을 하다가 알게 되었는데요, 이번 기회에 기억하고 프로젝트에 적용해보려고 합니다. collectAsState를 사용하고 있다면 collectAsStateWithLifecycle로 변경해봅시다!

 

 

 

 

 

Reference

https://medium.com/androiddevelopers/consuming-flows-safely-in-jetpack-compose-cde014d0d5a3