아래는 코모스튜디오가 직접 만든 무료 앱이에요(한 번만 봐주세요 ^^)
MutableLiveData는 Abstract Class 인 LiveData를 구현한 Public Class
위 말을 풀어 보면,
1. LiveData는 추상 클래스이므로 직접 생성할 수 없다.
public abstract class LiveData<T> {
protected void postValue(T value) {}
@MainThread
protected void setValue(T value) {}
//데이터 수정은 pretected 메서드를 구현해서 사용해야 한다.
}
val name : LiveData<String> = LiveData<String>()
위와 같이 직접 생성할 경우 아래와 같이 에러가 발생한다.
cannot create an instance of an abstract class
반면에 MutableLiveData는 일반 클래스이므로 아래와 같이 직접 생성하고 초기화도 할 수 있다.
public class MutableLiveData<T> extends LiveData<T> {
//protected 메서드를 public으로 구현
@Override
public void postValue(T value) {
super.postValue(value);
}
@Override
public void setValue(T value) {
super.setValue(value);
}
}
private mutableName : MutableLiveData<String> = MutableLiveData<String>()
private mutableName2 : MutableLiveData<String> by lazy{
MutableLiveData<String>()
}
2. LiveData는 변경될 수 없고, MutableLiveData는 변경될 수 있다는 말의 의미는
- LiveData는 주어진 라이프사이클(lifecycle) 내에서 관찰(observer)할 수 있는 data Holder 역할을 하는데,
- LiveData에 데이터를 Set 할 수 있는 것은 이를 구현한 클래스에서 setValue/postValue를 통해서만 가능하다는 의미이다.
1. val name : LiveData<String> = repository.getName()
//를 통해 직접 Room에서 생성한 LiveData를 직접 할당하거나,
2. val nameMutable = MutableLiveData<String>()
val name : LiveData<String> = nameMutable
//와 같이 mutableLiveData를 직접생성해서 LiveData에 연결 하는 방법을 사용 해야 한다는 것이다.
name.value = "abc"
와 같이 LiveData가 수정되는 것으로 보일 수 있으나, 실제로는 nameMutable이 수정되는 것이다.
3. 결국 관찰자가 사용하는 것은 모체인 LiveData로 동일 하나, 데이터를 쓸 수 있느냐의 문제라는 말의 의미를
- ViewModel에서 바라보면,
- ViewModel은 변경이 불가능한 LiveData 객체만 외부 관찰자에게 노출해야 한다.
- 즉, 외부(view 등)에서 LiveData는 변경이 불가능하게 해야 만들어야 한다는 것이다.
- 하지만, 이름이 LiveData인데 변경이 불가능하다면 의미가 없지 않은가?
- 그렇다면, LiveData의 데이터 변경은 누가 하는가?
- Room 라이브러리를 사용한다면 Room의 데이터가 바뀌면 해당 LiveData로 바뀐 Data를 즉시 수정해준다.
- Room 같은 라이브러리를 사용하지 않는다면 viewModel에서 MutableLiveData를 생성해서 LiveData와 연결 한 뒤, 모델의 로직에 따라 MutableLiveData를 수정해주면 된다.
- 즉, LiveData는 public으로 MutableLiveData는 private으로 선언해서 외부에서는 관찰을 내부에서는 수정을 하는 방식이 되어야 한다는 말이다.
- 결국, LiveData는 ViewModel과의 연결 고리가 되는 Data Holder 역할이고, MutableLiveData는 이 Data Holder에 값을 채우는(수정) 역할을 한다는 말이 된다.
4. LiveData와 MutableLiveData를 연결하는 또 다른 방법은?
- 위에서도 언급한 MutableLiveData를 생성해서 LiveData에 직접 할당하는 방법을 사용하거나,
- lifecycle.transformation의 switchMap을 사용하여 MutableLiveData가 변경될 경우 LiveData를 반환하면 된다.
private val nameMutable = MutableLiveData<String>(name)
val name : LiveData<String> = nameMutable.switchMap{name ->
repository.getName()
}
ViewModel에서 본 LiveData와 MutableLiveData는
외부와의 연결 고리(관찰자 제공및 Room 라이브러리의 데이터를 받는) 역할을 할 것이냐, 직접 가공하고 가공되는 데이터(setValue/postValue)로서의 역할을 할 것이냐에 따라 다르게 사용하면 된다.
모든 게시물은 코모스튜디오의 소유이며, 무단 복제 수정은 절대 불가입니다. |
퍼가실 경우 댓글과 블로그 주소를 남기고 해당 게시물에 출처를 명확히 밝히세요. |