[Android / Kotlin] Flow

Subeen·2024년 2월 18일
0

Android

목록 보기
61/73

비동기적으로 작업을 처리하는 코루틴에서 suspend 함수를 사용하면 작업이 모두 완료 된 후에 단일값만을 반환 받을 수 있다.
하지만, 중간 중간 진행 되는 코루틴 작업 중에 갱신 되는 값까지 반환받을 수 있다면 로직 업데이트를 더 촘촘히 수행할 수 있을 것이다.
Flow는 이런 요구를 충족하기 위해서 만들어진 타입
이다.

Flow

Flow는 빌더를 통해서 생성하는데 Suspend 키워드를 따로 붙여주지 않아도 블록 내부의 작업이 코루틴에서 수행 된다.
Flow에서 값을 방출하는 데에는 Emit을 사용하고, 값을 회수하는 데에는 Collect 함수를 사용한다.
Flow는 Collect로 값을 요청하지 않는 한 값을 방출하지 않는데, 이것을 Cold Stream이라고 한다.
반대로, Hot Stream은 요청이 있건 없건 값을 계속 방출하는 형식이다.

Flow vs LiveData

Repository 레벨에서는 Flow를 사용하고, UI와 레포지토리를 엮는 ViewModel단에서는 LiveData를 사용하기를 추천한다고 한다.

  • Flow는 코루틴 스코프 안에서 동작하기 때문에 ViewModel 스코프나 LifeCycle 스코프와 함께 사용하면 LiveData처럼 ViewModel 또는 Activity나 Fragment 생명주기에 맞춰서 동작을 실행하거나 정지할 수 있다.
  • 이렇다 할 연산자가 존재하지 않는 LiveData와 비교하면 Flow에는 풍부한 연산자가 있어서 데이터를 필요에 따라 유연하게 변환할 수 있다.
  • LiveData
    • 생명주기를 가진 데이터 홀더로 UI와 연결하면 자동으로 화면을 업데이트 할 수 있다는 이점
    • 메인 스레드에서 동작하므로 워커 스레드에서 작업을 처리해야 되는 데이터 레이어에서는 사용하기가 적절치 않다.
    • 안드로이드와 밀접하게 연결되어 있어 테스트가 까다로워진다.
  • Flow
    • CoroutineScope 안에서 동작하므로 필요에 따라 적당한 쓰레드를 골라서 사용할 수 있다.
    • 안드로이드 라이프사이클 감지 가능
    • 안드로이드 의존성 제거 가능
    • Cold Stream이므로 Collect가 되어야만 값을 방출한다.
    • 상태가 없으므로 현재 값을 얻을 수 없다는 한계가 있다.

SharedFlow로 LiveData 대체하기

SharedFlow

Hot Stream으로 동작하게 구성된 Flow의 한 종류이다.

StateFlow

SharedFlow에서 상태를 부여해서 현재 값을 얻을 수 있게 제안을 가한 것이 StateFlow이다.
LiveData와 비슷한 동작을 하면서도 UI에서 데이터 레벨까지 사용할 수 있는 데이터 홀더이다.
구글은 UI를 표시하는 데이터 홀더를 LiveData에서 StateFlow로 변경하고 있는 추세이다.

fun <T> Flow<T>.stateIn(scope: CoroutineScope, started: SharingStarted, initialValue: T): StateFlow<T>
  • scope : StateFlow가 작동할 scope
  • started : 구독을 시작하는 타이밍
  • initialValue : 초기 값
  • SharingStarted의 옵션
    • SharingStarted.Eagerly : collector가 존재하지 않더라도 바로 sharing이 시작되며 중간에 중지되지 않음
    • SharingStarted.Lazily : collector가 등록된 이후부터 sharing이 시작되며 중간에 중지되지 않음
    • SharingStarted.WhileSubscribed : collector가 등록되면 바로 sharing을 시작하며 collector가 전부 없어지면 바로 중지 됨
profile
개발 공부 기록 🌱

0개의 댓글