처음 글을 작성할 땐 'Rx vs LiveData'로 제목을 작성했었다. 이는 'LivaData를 사용하느냐 CoroutineFlow를 사용하느냐'의 질문과 같은 맥락일 것이다. 처음엔 LiveData의 Obserbable 변수에 새 데이터가 업데이트되면 UI 업데이트로 이어지기 때문에 RxJava와 같은 녀석이라고 생각했다. 왜 RxJava와 LiveData가 다른 녀석인지 이해하지 못했었다. 하지만 지금은 이 질문의 답을 어느정도 예측할 수 있다.
아래는 ReactiveProgramming의 개념을 모호하게 이해했을 때(물론 지금도 부족) LiveData와 RxJava의 개념이 헷갈려 찾았던 StackOverflow의 코멘트 중 하나이다. LiveData와 RxJava의 역할이 어떤 차이점을 가지고 있는지 아주 상세하게 알려준다. 원문을 번역하고 어색한 부분은 한글에 맞게 수정했다. 확실하게 이해한 부분에 한해서 첨언을 하기도 했다.
LiveData는 STREAM이 아니지만 RxJava에서는 모든 것(말 그대로 모든 것)이 STREAM이다.
LiveData는 관찰 가능한 데이터 홀더 클래스이다. 일반 옵저버블과 달리 LiveData는 수명 주기를 인식한다. 즉, LiveData는 액티비티, 프래그먼트 또는 서비스와 같은 다른 앱 구성 요소의 수명 주기를 인식할 수 있다. 이러한 인식은 LiveData가 활성 수명 주기 상태에 있는 앱 구성 요소 관찰자만 업데이트하도록 한다.
LiveData는 동기식이다. 따라서 LiveData만 사용해선 비동기적으로 코드 청크(네트워크 호출, 데이터베이스 조작 등)를 실행할 수 없다. 하지만 RxJava는 이것이 가능하다는 뜻이다. 애초에 RxJava를 큰 틀에서 보면, 비동기 처리를 위해 존재하는 개념 및 기능이기 때문이다.
이 LiveData와 RxJava의 듀오를 최대한 활용하기 위해 할 수 있는 최선의 방법은 (1) 비즈니스 로직(네트워크 호출, 데이터 조작 등, Repository 안팎에서 발생하는 모든 것)에 RxJava를 사용하고, (2) 프레젠테이션 계층에 LiveData를 사용하는 것이다. 이를 통해 비즈니스 로직에 대한 변환 및 스트림 기능과 UI에 대한 수명 주기 인식 작업 모두를 얻을 수 있다. (3) 하지만 Coroutine Flow의 경우, 비동기 데이터 스트림 처리에 최적화된 데이터 홀더 클래스로 StateFlow가 존재하는 것을 우린 추가로 알고 있다. 이를 통해 우리의 선택권이 늘어났다는 것을 명심하자.
.
결국 LiveData와 RxJava 는 함께 사용하면 서로를 보완한다는 것이다. RxJava로 (비동기 데이터 스트림 처리에 관한) 모든 것을 하고 마지막에 UI를 업데이트하고 싶을 때 Observable을 LiveData로 변경하면 된다는 것. 이렇게 코드를 작성하면 기존의 MVVM과 같이, View는 ViewModel의 LiveData를 관찰하게 된다.
.
즉 RxJava에서 MutableLiveData(또는 LiveData)로의 응답을 저장하고 LiveData는 수명 주기를 인식하므로 데이터가 View의 수명 주기를 인식하게 된다. 데이터 자체가 UI를 업데이트할 때와 업데이트하지 말아야 할 때(View 수명주기 활성화/비활성화 시기)를 알고 있을 때의 가능성을 상상해보자. 아주 멋지다.
RxJava와 다르게 LiveData에는 기록이 없다. 현재 상태의 데이터만 가지고 있을 뿐이다. RxJava는 비동기적인, 순차적 데이터 스트림을 다룬다. 따라서 채팅 애플리케이션에 LiveData를 사용하면 안 된다고 한다.
RxJava와 함께 LiveData를 사용하면 MediatorLiveData , SwitchMap 등과 같은 항목이 필요하지 않다. 이들은 스트림 제어 도구이며 RxJava가 여러 번 더 좋다.
LiveData와 CoroutineFlow를 함께 사용하면
ViewModel과 View 사이의 상호작용은 LiveData가,
더 깊은 레이어와 스레딩과 같은 더 복잡한 처리는 Flow가 책임을 지는 역할을 하게 됩니다.