[JetPack] LiveData
-
LiveData : Activity, Fragment등의 수명주기를 인식하는 데이터 홀더 클래스. RxJava의 Observable과 비슷하게 Observer가 구독할 수 있는 데이터 흐름을 발행하는 Observer패턴을 따르며 현재의 수명주기가 STARTED나 RESUMED인 옵저버에게만 데이터를 발행한다.
-
LiveData.observe(LifecycleOwner, Observer
)를 통해 구독하고, LifecycleOwner객체를 함께 전달한다. 이 객체를 통해 LiveData는 수명주기를 자동으로 인식하게 된다. 비활성상태에서 다시 활성상태로 돌아오면 최신의 데이터를 자동으로 받는다. -
옵저버는 Lifecycle객체와 결합되어 있으며 수명주기가 끝나면 자동 삭제된다.
-
LiveData인스턴스는 대개 ViewModel클래스에서 by lazy 구문을 통해 val로 생성된다.(getter로 접근할라고)
-
액티비티나 프레그먼트 등에서 Observer를 생성하고, LiveData를 observe()하며 구독을 시작한다.
-
observeForever, removeObserver를 이용해 생명주기에 관계없이 구독, 구독취소도 가능하다.
-
보통 ViewModel은 LiveData 포함, 데이터 발행을 하고 Activity or Fragment에서 viewModel을 주입받거나 소유하고 liveData를 구독, 데이터없이 UI만 업데이트
-
LiveData
: 데이터 타입을 래핑함 -
Observer(Activity or Fragment)의 onCreate()에서 LiveData의 구독을 시작하기에 적합함. onResume()에서의 중복 초기화를 방지하고, STARTED상태에서 곧바로 최신 데이터를 받기에 적합하기 때문
-
LiveData는 데이터를 업데이트하는 공개 메소드가 없는 대신 MutableLiveData에는 setValue(T), postValue(T)가 있다. 일반적으로 MutableLiveData가 ViewModel에서 사용되면 ViewModel은 변경할 수 없는 LiveData 개체만 관찰자에게 노출한다.
-
UI스레드에서는 setValue(), 워커 스레드에서는 postValue(T)를 호출한다.
-
Room라이브러리는 LiveData를 반환하도록 설정할 수 있다. 이 경우 Database가 업데이트 되면 Room에서는 LiveData를 업데이트 하며 데이터베이스와 UI를 자동으로 동기화 한다.
-
Coroutine을 지원한다. 자세한 내용은 링크 참고 : [아키텍처 구성요소와 함께 Kotlin 코루틴 사용][https://developer.android.com/topic/libraries/architecture/coroutines?hl=ko]
-
override fun onActive() : 활성 옵저버가 존재할 때 호출. 여기서 Repository에서의 업데이트 옵저빙을 시작해야 한다.
-
override fun onInActive() : 활성 옵저버가 없을 때 호출. Repository에서의 업데이트 옵저빙을 끝낼 수 있다.
-
Observer객체는 Lifecycle객체가 활성상태가 아니면 값이 변경되더라도 옵저버가 호출되지 않으며 Lifecycle객체가 폐기되면 Observer객체도 함께 삭제된다.
-
Transformations객체를 이용해 RxJava의 Observable객체처럼 map, flatMap등을 사용해 옵저버에게 전달하기 전에 값을 변환할 수 있다.
val userLiveData: LiveData<User> = UserLiveData()
val userName: LiveData<String> = Transformations.map(userLiveData) {
user -> "${user.name} ${user.lastName}"
}
- 아래와 같이 getpostalCode를 호출할 때 마다 새 LiveData를 구독하도록 만들지 말 고 Toansformations객체를 이용할 것.
class MyViewModel(private val repository: PostalCodeRepository) : ViewModel() {
private fun getPostalCode(address: String): LiveData<String> {
// DON'T DO THIS
return repository.getPostCode(address)
}
}
-
MediatorLiveData : LiveData의 서브클래스이며 LiveData를 병합할 수 있고, 병합 후 이 객체의 옵저버는 원본 객체가 업데이트 될 때 마다 함께 업데이트 된다.
-
디펜던시 추가
implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:$lifecycle_version"