LiveData
Flow
Corotine의 Flow는 데이터 스트림이며 코루틴 상에서 Reactive Programing을 지원하기 위한 구성요소이다.
ReactivePrograming
- 데이터가 변경될 때 이벤트를 발생시켜 데이터를 계속 전달하도록 하는 프로그래밍 방식
- 기존 명령형 프로그래밍은 소비자가 데이터를 요청한 후 결과값을 일회성으로 수신한다.
하지만 이런 방식은 결과값이 필요할 때마다 계속해서 요청을 해야한다.- 리액티브 프로그래밍에서는 데이터를 발행하는 발행자가 있고 소비자는 발행자에게 구독 요청을 한다.
그러면 발행자는 새로운 데이터가 들어오면 소비자에게 지속적으로 발행한다.
리액티브 프로그래밍에는 데이터를 발행하는 발행자가 있고 발행자는 소비자에게 지속적으로 데이터를 전달한다. 이것을 데이터 스트림 이라고 부른다.
💡 **Flow History**Flow가 나온 여러가지 이유 중 하나는 코틀린이 멀티플랫폼으로 사용되면서입니다.
View와 Repo의 의존성이 심하게 되어있는 LiveData는 불편해지기 시작했습니다.
각각을 모듈화하는데 View와 Repo의 의존성을 낮추어야 하기 때문입니다.
(그림 1 ) 구글 공식 문서
데이터 스트림에는 3가지 구성요소가 존재한다.
먼저 생산자는 데이터를 발행한다.
생산자는 flow{ } 블록 내부에서의 emit()을 통해 데이터를 생성한다.
기본적으로 데이터소스는 두가지이다.
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
}
}
}
생산자가 데이터를 생성했다면 중간 연산자는 생성된 데이터를 수정한다.
예를 들어 생성자가 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
}
}
}
}
중간 연산자가 변형한 데이터는 소비자에게 전달된다. Flow에서는 collect를 이용해 전달된 데이터를 소비할 수 있다.
안드로이드에서의 데이터 소비자는 주로 UI구성 요소로
Activity, Dialog, Fragment와 같은 것들이 속한다.
예시
class UserFragment() : Fragment{
onViewCreated(){
lifecycleScope.launch{
launch{
viewModel.getManUser().collect{
binding.name.text = it.name
}
}
}
}
}