LiveData
- 식별 가능한 Data Holder Class
(식별 가능한 일반 클래스와 달리 LiveData는 수명 주기를 인식한다.
- LiveData는 active한 상태(STARTED or RESUMED)일때만 감싸고 있는 데이터의 변경을 알려줍니다.
- LiveData 객체는 Observer 객체와 함께 사용됩니다. LiveData가 가지고 있는 데이터에 어떠한 변화가 일어날 경우, LiveData는 등록된 Observer 객체에 변화를 알려주고, Observer의 onChanged()가 실행되게 됩니다.
LiveData가 어떻게 생명주기를 알까?
- LifeCycleOwner라는 인터페이스가 안드로이드 생명주기를 알고 있는 클래스이다. 이는 오직 getLifeCycle()만을 가지고 있는 단일 메서드 인터페이스이며, Activity나 Fragment에서 이를 상속하고 있습니다.
- 한마디로 LiveData의 Observer 메서드의 LifeCycleOwner를 Activity나 Fragment를 변수로 사용한다면 각 화면 별 생명 주기에 따라 LiveData는 동작을 하게 됩니다.
LiveData 동작
- onStart, onResume과 같은 상태일때만 변경을 처리하고, onStop과 같은 상태라면 데이터 변경을 처리하지 않는다. 만약 어떤 Activity가 원래의 화면으로 돌아와서 onResume이 호출된다면, LiveData는 가장 마지막에 변경된 최신 데이터를 실행한다.
- LiveData는 onActive와 onInactive 함수가 있어서 active Observer들이 0과 1사이로 변경될 때 notify 받을 수 있다.
LiveData를 사용함으로써 얻을 수 있는 장점
- Data와 UI간 동기화
- 메모리 누수 없음
- Stop 상태의 액티비티와 Crash가 발생하지 않습니다.
- 생명주기에 대한 추가적인 handling을 하지 않아도 된다.
- 항상 최신 데이터 유지
- Resource를 공유 할 수 있습니다.
setValue / postValue
- setValue() : 메인 스레드에서 LiveData의 값을 변경해준다. 메인 스레드에서 바로 값을 변경해주기 때문에 setValue() 함수를 호출한 뒤 바로 빝에서 getValue() 함수로 값을 읽어오면 변경된 값을 가져올 수 있다.
- 중요한 점은, setValue()는 메인 스레드에서 값을 dispatch 하기 때문에 백그라운드에서 setValue()를 호출한다면 오류가 나게 된다. setValue()가 동작하지 않는다면, 해당 함수가 호출되는 스레드가 메인 스레드인지 체크해봐야 한다.
- postValue() : setValue()와 다르게 백그라운드에서 값을 변경한다. 백그라운드 스레드에서 동작하다가 메인 스레드에 값을 post 하는 방식으로 사용된다. 함수 내부적으로 아래와 같다.
new Handler(Looper.mainLooper()).post(() -> setValue())
- 메인 스레드에 적용되기 전에 postValue()가 여러 번 호출된다면 모든 값이 적용되는 것이 아니라 가장 최신의 값이 적용된다. 따라서 postValue를 호출한 뒤 바로 getvalue()로 값을 읽으려고 한다면 변경된 값을 읽어오지 못할 가능성이 높다. Handler()를 통해 메인 스레드에 값이 전달되기 전에 getValue()를 호출하기 때문이다. LiveData의 값을 즉각적으로 변경해야 한다면 postValue()가 아닌 setValue()를 사용해야 한다.