관리 메뉴

나만을 위한 블로그

[Android] StateFlow, SharedFlow Best Practices 본문

Android

[Android] StateFlow, SharedFlow Best Practices

참깨빵위에참깨빵 2023. 8. 27. 20:07
728x90
반응형

※ 이 포스팅은 SteteFlow와 SharedFlow를 알고 있는 것을 전제로 한다

 

이 포스팅은 아래의 미디엄 포스팅을 번역한 글이다.

 

https://medium.com/@mortitech/sharedflow-vs-stateflow-a-comprehensive-guide-to-kotlin-flows-503576b4de31

 

SharedFlow vs. StateFlow: Best Practices and Real-world examples

Dive into the world of Kotlin flows with this in-depth comparison of SharedFlow and StateFlow. Here’s an overview of both types of flows…

medium.com

 

먼저 StateFlow, SharedFlow의 특징을 간단하게 정리하면 아래와 같다.

 

StateFlow SharedFlow
Hot Flow
초기값 설정 필요 초기값 설정 필요 없음
가장 최근값만 갖고 있음 가장 최근 N개의 값을 갖고 있음
value 프로퍼티로 값을 읽거나 설정할 수 있음 값을 emit할 수 있지만 직접 읽을 수는 없음

 

이제 Best Practice들을 확인해 본다. Best Practice라고 하지만 대부분이 이미 알고 있는 내용들일 것이다.

 

Flow를 적절히 알맞게 사용한다

 

UI 등에서 하나의 상태값을 최신 상태로 업데이트해야 한다면 StateFlow, 여러 collector에 값을 보내거나 같은 데이터 스트림에서 여러 구독자를 갖고 있어야 한다면 SharedFlow를 사용한다.

즉 각 Flow의 특성에 맞춰 상황별 알맞은 Flow를 사용하는 것이 첫 번째 Best Practice다.

 

mutable flow는 캡슐화하라

 

참고 코드를 찾아보면 LiveData도 private val과 val의 2가지 프로퍼티로 나눠두고 사용하듯 Flow도 이렇게 사용한다.

이렇게 하는 이유는 외부에서 값의 변경을 막기 위함이다.

LiveData를 2가지 프로퍼티로 나눠 사용하던 사람은 지금까지 해 온 것처럼 StateFlow, SharedFlow를 사용하면 된다.

 

private val _mutableStateFlow = MutableStateFlow(1)
val stateFlow = _mutableStateFlow.asStateFlow()

private val _mutableSharedFlow = MutableSharedFlow<Int>()
val sharedFlow = _mutableSharedFlow.asSharedFlow()

 

asStateFlow()를 사용하지 않아도 문제는 없다. MutableStateFlow, MutableSharedFlow는 이미 StateFlow, SharedFlow 인터페이스를 구현하고 있기 때문이다. 코드를 읽는 사람에게 더 명확하게 읽기 전용이란 의도와 해당 Flow는 수정할 수 없다는 걸 전달하기 위해 사용한 것이다.

 

리소스 관리

 

각 Flow를 사용할 때 코루틴, 컬렉터가 더 이상 필요하지 않다면 취소하는 게 좋다. 메모리 누수를 막기 위함이다.

 

buffer, replay 구성을 적절하게 사용하기

 

SharedFlow에선 버퍼 용량, replay 용량을 설정할 수 있다. 배압 문제를 방지하려면 적절한 버퍼 용량을 선택하고 요구 사항에 따라 replay 용량을 설정해야 한다. StateFlow의 경우 항상 크기가 1인 replay 캐시가 존재한다. 이는 새 collector에 대한 최신 값을 유지한다는 뜻이다

 

combine, map, filter 등의 연산자 사용

 

필요에 따라 데이터를 변환, 결합, 필터링하면 더 표현력 있고 효율적인 코드 작성에 도움이 된다.

 

lifecycleScope, RepeatOnLifecycle, 기타 생명주기 인식 연산자 사용

 

생명주기를 인식하는 연산자를 활용해서 Flow의 생명주기를 자동으로 관리하는 게 좋다. repeatOnLifecycle {}은 잘못 사용하면 내가 원하는 결과가 나오지 않을 수 있기 때문에 사용에 유의해야 한다.

반응형
Comments