원래는 ViewModel
클래스에 대해 다뤄야할 차례이지만 ViewModel
에 대해서는 최근에 한번 간단하게 다뤄본 적이 있기 때문에 건너 뛰고 LiveData
클래스에 대해 알아보자.
LiveData
는 관찰 가능한 (Observable) 데이터 홀더 클래스이다. 관찰 가능한 다른 클래스들과 달리 생명 주기를 인식한다는 게 가장 큰 특징이다.
LiveData
는 Activity
, Fragment
, Service
등 앱 컴포넌트들의 생명 주기를 인식하고 활동 중인 상태의 앱 컴포넌트의 관찰자만 업데이트해준다.
Observer
클래스가 STARTED
또는 RESUMED
상태이면 활성화 상태로 간주하고 데이터 업데이트 정보를 알린다.LiveData
는 데이터가 변경되면 Observer
객체에 알리고 UI를 업데이트한다. 앱 데이터가 변경될때마다 관찰자가 UI를 업데이트하므로 개발자가 직접 코드로 업데이트 할 필요가 없다.
Observer
클래스는 연결된 앱 컴포넌트의 생명 주기가 끝나면 자동으로 삭제된다.
Observer
의 생명 주기가 비활성 상태이며 어떤 LiveData
이벤트도 받지 않는다.
UI 컴포넌트는 데이터 변화를 관찰하기만 한다. LiveData
는 생명 주기 상태의 변화를 인식해 자동으로 처리해준다.
생명주기가 비활성화 되었다가 다시 활성화될 때 최신 데이터를 수신한다.
기기 회전과 같은 구성 변경으로 인해 활동 또는 프래그먼트가 다시 생성되면 사용 가능한 최신 데이터를 즉시 받게 됩니다.
앱에서 시스템 서비스를 공유할 수 있도록 싱글톤 패턴을 사용하는 LiveData
객체를 확장하여 시스템 서비스를 래핑할 수 있습니다. LiveData
객체가 시스템 서비스에 한 번 연결되면 리소스가 필요한 모든 관찰자가 LiveData
객체를 볼 수 있습니다.
LiveData
객체는 일반적으로 ViewModel
객체 내에 저장된다.
보통 액티비티나 프래그먼트 같은 앱 컴포넌트의 onCreate()
메소드에서 LiveData
객체의 관찰을 시작한다. 그 이유는 아래와 같다.
Activity
및 Fragment
가 활성 상태가 되는 즉시 표시할 수 있는 데이터를 포함하기 위해서이다.또한 Observer
가 LiveData
로부터 업데이트를 받는 경우는 3가지가 있다.
LiveData
의 데이터가 변경되고 Observer
가 활성 상태일 때.Observer
가 비활성 상태에서 활성 상태로 변경될 때.Observer
가 비활성 상태에서 활성 상태로 두 번째로 변경되고 마지막으로 활성 상태가 된 이후와 값이 변경되었을 때.class NameViewModel : ViewModel() {
// Create a LiveData with a String
val currentName: MutableLiveData<String> by lazy {
MutableLiveData<String>()
}
// Rest of the ViewModel...
}
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)
}
}
Observer
클래스의 인스턴스인 nameObserver
객체를 선언 후 model.currentName
이라는 LiveData
를 관찰한다.
처음 observer()
를 호출했을 때 mCurrentName
에 값이 설정되어 있다면 onChanged()
메소드가 즉시 호출된다.
LiveData
객체 자체에는 저장된 데이터를 업데이트하는데 사용할 수 있는 public 메소드가 존재하지 않는다.
대신 보통 MutableLiveData
클래스의 setValue()
, postValue()
메소드를 이용한다. 일반적으로 MutableLiveData
는 ViewModel
클래스 내에서만 사용되며 ViewModel
은 변경이 불가능한 LiveData
객체만 관찰자에게 노출시킨다.
class MainViewModel: ViewModel() {
// MutableLiveData는 수정이 가능함
private val _winner = MutableLiveData<Int>()
private var _maxNumber = MutableLiveData<Int>()
// LiveData는 외부에서 수정이 불가능하게 설정
// getter를 사용하여 데이터를 읽는 과정만 수행 가능
val winner: LiveData<Int>
get() = _winner
val maxNumber: LiveData<Int>
get() = _maxNumber
// LiveData를 수정하는 함수
fun updateMaxNumber(maxNumber: Int) {
_maxNumber.value = maxNumber
}
fun updateWinner(winner: Int) {
_winner.value = winner
}
}
위와 같이 데이터 업데이트는 MutableLiveData
객체를 통해서 진행하고 ViewModel
이 업데이트된 데이터를 전달할 때는 LiveData
객체의 형태로 전달해서 함부로 수정할 수 없게 한다.