조각들

개요

예전에도 flow 공부를 잠깐 했었는데 그때는 이게 왜 필요한지 모르니까 내용이 눈에 잘 안 들어왔고 "LiveData만으로도 충분한 것 같은데 이걸 써야할까?"라는 생각에 활용을 적극적으로 하진 않았다. 써보긴 했지만 "한 번 써보기나 할까?"였고 이게 유용하게 쓰일 수 있는 배경을 모르니 의미없는 작업이었다. 그러다 최근에 회사에서 flow를 배울 필요성을 느꼈다. 그래서 다시 찾아보게됐다. 


배경

근본적인 문제는 그동안 activity 재성성에 대한 고려가 별로 없이 개발을 해왔다는 것이다. 안정성 측면에서 엉망으로 해왔단 얘기다. 화면을 돌리거나 다크모드를 키면 화면 data가 날아가거나 onCreate() 안에 넣어놓은 logic이 싹 다시 돌면서 의도하지 않은 상황이 생기곤 했다. 

 

같은 맥락으로 옵저버 쪽에서도 문제가 있었다. 1회성으로 처리할 event인데 화면이 재생성되고 옵저버도 다시 생겨나면서 그 안에 넣어둔 logic이 다시 돌았다. 

 

옵저버를 커스텀으로 만들어서 이미 처리한 event이면 다시 처리되지 못하게 할 수 있지만 나는 이러한 방법을 몰랐다. 피드백을 받고나서야 알았는데 사수분이 flow를 쓰면 이렇게 옵저버를 커스텀으로 안 만들어주고도 가능하다는 얘기를 해주셨다.

 

그래서 지속적으로 옵저빙이 필요한 상황과 1회성 event를 구분하고 더 편하게 처리하기 위해 flow를 다시 찾게 되었다. 


공부 내용

Cold? Hot?

쉽게 얘기하자면 flow (빌더) 블록 안의 상태를 다른 collecter들과 공유하는지의 차이라고 이해했다. 공유를 하면 Hot, 공유를 안 하면 Cold이다. 마치 Fragment끼리는 하나의 뷰모델을 공유하여 작업되고 있던 data의 상태를 그대로 이어받아올 수 있는 것과 비슷한 느낌이었다. 

 

Flow(Cold), StateFlow(Hot), SharedFlow(Hot)

  • 기본적으로 Flow는 Cold flow인데 stateIn, sharedIn을 통해 hot flow로 변환할 수 있다. 
  • LiveData-옵저버는 생명주기를 인식해서 앱이 활성화 상태일 때만 동작한다는 편리함이 있는데 flow는 repeatOnLifecycle 등으로 flow가 돌려질 시점을 직접 지정을 해줘야 한다. 위처럼 지정을 해주면 LiveData와 동일한 효과를 낸다고 한다.
  • StateFlow는 초기값을 가진다.
  • StateFlow는 동일한 값을 (중복으로) emit 시도 시 emit 되지 않는다.
  • StateFlow는 마지막에 emit 된 값을 저장한다. 따라서 새로운 collect이 발생하면 자동으로 저장하고 있던 마지막 값을 collector에게 전달한다. 이러한 문제로 StateFlow를 쓰면 activity 재생성 시 collect 블럭 내부 logic이 다시 돌게 되므로 1회성 이벤트 처리에부적절하다.
  • SharedFlow는 기본적으로 마지막에 발행된 값을 보유하지 않는다.(단, replay 파라미터를 0 이상으로 설정한 경우 제외). 이는 SharedFlow가 새로운 구독자에게 자동으로 최신 값이나 이벤트를 다시 전송하지 않는다는 의미이다.  즉, 이벤트가 발생한 그 순간에만 수집하고 있는 collector에게 전달된다. 이러한 특징 때문에 SharedFlow는 1회성 이벤트 처리에 적절하다.

느낀점

편의성을 높여주는 중간 연산자가 많다고 느꼈다. 아직 직접적인 체감은 안 되지만 이러한 점 때문에 자율성이 높고 여러 상황에 대한 커스텀 대응이 수월할 것 같다. 대신 자율성이 높으면 그만큼 책임과 수고가 따른다. flow를 쓰면 domain 쪽에 안드로이드 의존성 없이 순수 코틀린으로 구성이 가능해진다고는 하는데 지금은 잘 모르겠다.

 

당장은 중간 연산자에 대한 공부가 더 필요할 것 같다.

'Android > 공부' 카테고리의 다른 글

코루틴  (0) 2024.05.30
retrofit의 비동기 처리  (0) 2024.04.29
Repository의 효용에 대한 고찰  (0) 2023.03.16
[공부] Github Action CI  (0) 2023.03.04
[공부] MVVM, ViewModel, LiveData, DataBinding, Fragment  (1) 2023.01.21