post-custom-banner

LiveData vs Flow 간단 비교

LiveData

  • 데이터를 담고 있는 데이터 홀더 클래스이다.
  • Lifecycle을 인식하고있다.
  • Lifecycle을 따로 관리하지 않아도 된다.
  • 모든 구독자(신규 + 기존)는 항상 최신 데이터를 받는다
  • 데이터를 한번만 사용하기 위해서는 기본적으로 boolean을 이용한다.(Event)

Flow

  • 코루틴 위에 구축
  • 순차적 계산이 가능한 데이터 스트림
  • 스트림을 수정할수 있는 중간 연산자(map,filter)를 제공한다.
  • 수명주기를 인식하지 않는다.(원한다면 lifecycleScope를 이용하여 인식하게 만들 수 있다.)
    • ColdFlow ( Flow )
      • flow의 {}내부 블록이 만들어 질 때까지 활성화 되지 않음.
      • 수집 전과 수집 종료 후에는 비활성화
      • 구독자는 한명만 가진다.
      • 새로운 구독자는 새로운 실행을 생성한다.
      • 아무것도 하지 않을때에는 return, event가 발생할 때에만 시작하기 떄문에 flow를 리턴하는 함수에는 suspend가 없다.
    • HotFlow ( SharedFlow, StateFlow)
      • 여러 수집가 간에 공유가 가능하다.
      • 항목을 여러 소비자에게 전파한다.

Flow

Flow란?

Corotine의 Flow는 데이터 스트림이며 코루틴 상에서 Reactive Programing을 지원하기 위한 구성요소이다.

ReactivePrograming

  • 데이터가 변경될 때 이벤트를 발생시켜 데이터를 계속 전달하도록 하는 프로그래밍 방식
  • 기존 명령형 프로그래밍은 소비자가 데이터를 요청한 후 결과값을 일회성으로 수신한다.
    하지만 이런 방식은 결과값이 필요할 때마다 계속해서 요청을 해야한다.
  • 리액티브 프로그래밍에서는 데이터를 발행하는 발행자가 있고 소비자는 발행자에게 구독 요청을 한다.
    그러면 발행자는 새로운 데이터가 들어오면 소비자에게 지속적으로 발행한다.

리액티브 프로그래밍에는 데이터를 발행하는 발행자가 있고 발행자는 소비자에게 지속적으로 데이터를 전달한다. 이것을 데이터 스트림 이라고 부른다.

💡 **Flow History**

Flow가 나온 여러가지 이유 중 하나는 코틀린이 멀티플랫폼으로 사용되면서입니다.
View와 Repo의 의존성이 심하게 되어있는 LiveData는 불편해지기 시작했습니다.
각각을 모듈화하는데 View와 Repo의 의존성을 낮추어야 하기 때문입니다.


(그림 1 ) 구글 공식 문서

데이터 스트림에는 3가지 구성요소가 존재한다.

  • Producer(생산자)
  • Intermediary(중간 연산자)
  • Consumer(소비자)

Producer(생산자)

먼저 생산자는 데이터를 발행한다.

생산자는 flow{ } 블록 내부에서의 emit()을 통해 데이터를 생성한다.

기본적으로 데이터소스는 두가지이다.

  • 서버의 데이터로 REST API를 이용해 가져온다.
  • 핸드폰상의 DB이며 Room, SharedPreference, DataStore등을 이용해 가져온다.

dataStore 예시

class UserDataStore(
		private val service : ApiService
){
		fun getUserInfo() : Flow<List<User>> = flow{
				val userInfos = service.getUserInfo()
				if(userInfos.isSuccessful){
						userInfos.body?.let{
								emit(it)
						}
				else{
						throw ErrorException
				}
		}
}

InterMediary(중간 연산자)

생산자가 데이터를 생성했다면 중간 연산자는 생성된 데이터를 수정한다.

예를 들어 생성자가 A라는 객체로 이루어진 데이터를 발행했다.
하지만 우리가 필요한 것은 어떤 특정 기준을 넘는 데이터들만으로 이루어진 B라는 객체 데이터가 필요한 경우

위와 같은 예시의 경우 Flow에서 제공하는 중간 연산자를 이용하여 A → B로 객체를 바꾼다.

대표적인 중간 연산자는 map(데이터 변형),filter(데이터 필터링),onEach(데이터마다 연산 수행)이 있다.

예시

class UserRepository(
		private val userDataStore : UserDataStore
){
		fun getManUser() = userDataStore.getUserInfo().map{
						it.filter{
								this.gender == Gender_MAN
						}
				}
		}
}

Consumer(소비자)

중간 연산자가 변형한 데이터는 소비자에게 전달된다. Flow에서는 collect를 이용해 전달된 데이터를 소비할 수 있다.

안드로이드에서의 데이터 소비자는 주로 UI구성 요소로
Activity, Dialog, Fragment와 같은 것들이 속한다.

예시

class UserFragment() : Fragment{

		onViewCreated(){
				lifecycleScope.launch{
						launch{
								viewModel.getManUser().collect{
										binding.name.text = it.name
								}
						}
				}
		}
}

profile
러닝커브를 따라서 등반중입니다.
post-custom-banner

0개의 댓글