관찰 가능한(Observable) 데이터 클래스로 Lifecycle을 통해 생명주기를 인식하고 activity나 fragment, service와 컴포넌트들의 생명 주기를 따른다.
LiveData
는 데이터 변경을 활성화된 Observer
를 통해서 알려주는데 주어진 LifecycleOwner
의 생명주기가 STARTED
또는 RESUME
인 경우에만 Observer
를 활성(active)
상태로 간주한다.
LiveData
의 observe
메소드를 통해 Observer
를 등록할 수 있고, LifecycleOwner
구현체가 DESTROYED
상태가 되면 자동으로 Observer
는 내부에서 제거된다.
장점
LiveData
는 변화를 Observer
에게 알리고 Observer
객체에서 데이터 변경에 따른 UI를 갱신할 수 있다.Observer
는 Lifecycle
에 바인딩되며, 생명 주기 상태가 DESTROYED
되면 스스로 제거되므로 별도의 리소스를 해제하는 코드를 작성할 필요가 없다Activity
가 백스택으로 들어가는 경우와 같이 Observer
가 비활성화된 상태일 때는 LiveData
로 부터 어떠한 이벤트도 받지 않아 안전하다.LiveData
에 LifecycleOwner
를 위임한 후로 자동으로 생명 주기 상태에 따라 관리한다.LiveData
를 상속하여 싱글턴 패턴으로 사용할 수도 있다. 안드로이드 서비스 같은 곳에 한 번만 연결하고, 애플리케이션 내 어디에서나 다중으로 접근하여 이 서비스를 관찰할 수 있다.특정 유형의 데이터를 보유할 LiveData
의 인스턴스를 생성한다. 이 작업은 일반적으로 ViewModel
클래스 내에서 이루어진다.
onChanged
메소드를 정의하는 Observer
객체를 만든다. 이 메소드는 LiveData
가 보유한 데이터가 변경될 때 발생하는 작업을 제어한다. 일반적으로 activity나 fragment 같은 UI 컨트롤러에 Observer
객체를 만든다.
observe(LifecycleOwner, Observer)
메소드를 이용해 LiveData
에 Observer
를 연결한다. 일반적으로 activity나 fragment 같은 UI 컨트롤러에 Observer
객체를 연결한다.
observeForever(Observer)
메소드를 사용하면 연결된LifecycleOwner
객체가 없는Observer
를 등록할 수 있다. 이 경우Observer
는 항상active
로 간주되어 항상 데이터 변경에 관한 알림을 받는다.
removeObserver(Observer)
메소드를 호출하여 이러한Observer
를 삭제할 수 있다.
-> LiveData
에 저장된 데이터 값이 업데이트되면 연결된 LifecycleOwner
가 active
상태에 있는 모든 등록된 Observer
를 트리거한다. 이로 인해 LiveData
에서 보유한 데이터가 변경되면 UI가 자동으로 업데이트 된다.
LiveData
는 일반적으로 ViewModel
객체 내에 저장되며 getter 메소드를 통해 액세스된다. 초깃값은 null
이다.class NameViewModel : ViewModel() {
// Create a LiveData with a String
val currentName: MutableLiveData<String> by lazy {
MutableLiveData<String>()
}
// Rest of the ViewModel...
}
ViewModel
에 LiveData
객체를 저장하는 이유는
- Activity나 Fragment가 커지는 걸 방지
(UI 컨트롤러는 데이터 표시 담당만!! 데이터 상태 보유는 x)LiveData
인스턴스를 특정 activity나 fragment에 의존하는걸 분리시켜서 구성 변경에도LiveData
객체가 유지되도록 하기 위해서!
onCreate
에서 LiveData
를 관찰하기 적합한데 그 이유는
onResume()
에서 중복 호출을 하지 않기 위해서- activity나 fragment가
active
상태가 되는 즉시 표시할 수 있는 데이터가 포함되도록 하기 위해서다.
(앱 컴포넌트는STARTED
상태가 되는 즉시 관찰하고 있던LiveData
의 가장 최신 값을 받게 된다. 이는 관찰할LiveData
객체가 설정된 경우에만 발생한다)
class NameActivity : AppCompatActivity() {
// Use the 'by viewModels()' Kotlin property delegate
// from the activity-ktx artifact
private val model: NameViewModel by viewModels()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
// Other code to setup the activity...
// Create the observer which updates the UI.
val nameObserver = Observer<String> { newName ->
// Update the UI, in this case, a TextView.
nameTextView.text = newName
}
// Observe the LiveData, passing in this activity as the LifecycleOwner and the observer.
model.currentName.observe(this, nameObserver)
}
}
LiveData
는 읽기만 가능하므로 데이터를 쓰려면 MutableLiveData
를 사용해야 한다. MutableLiveData
도 생성한 직후의 초깃값은 null
이다.
setValue()
, postValue()
로 데이터를 수정한다.
단, setValue()
는 메인 스레드에서만 호출해야 한다. postValue()
는 주로 백그라운드 스레드에서 호출하는 용도로 사용된다.
postValue()
의 경우 값을 설정하는 task를 내부에서 handler를 통해 메인스레드로 전달하는데, 그래서 메인 스레드가 실행되기 전에 postValue()
를 여러 번 호출해도 가장 마지막에 설정된 값만 가져온다.
button.setOnClickListener {
val anotherName = "John Doe"
model.currentName.setValue(anotherName)
}