[안드로이드 공부]/JetPack

LiveData 와 MutableLiveData

코코모아 2021. 3. 25. 16:10

아래는 코모스튜디오가 직접 만든 무료 앱이에요
(한 번만 봐주세요 ^^)

01

02

03

정각알림 만들기(말하는시계)

말하는 시계 (취침, 자전거) 

말하는 타이머 음성 스톱워치 

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를 수정해주면 된다.
    • 즉, LiveDatapublic으로 MutableLiveDataprivate으로 선언해서 외부에서는 관찰을 내부에서는 수정을 하는 방식이 되어야 한다는 말이다.
  • 결국, LiveData는 ViewModel과의 연결 고리가 되는 Data Holder 역할이고, MutableLiveData는 이 Data Holder에 값을 채우는(수정) 역할을 한다는 말이 된다.

4. LiveData와 MutableLiveData를 연결하는 또 다른 방법은?

 

  1. 위에서도 언급한 MutableLiveData를 생성해서 LiveData에 직접 할당하는 방법을 사용하거나,
  2. 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)로서의 역할을 할 것이냐에 따라 다르게 사용하면 된다.

모든 게시물은 코모스튜디오의 소유이며, 무단 복제 수정은 절대 불가입니다.
퍼가실 경우 댓글과 블로그 주소를 남기고 해당 게시물에 출처를 명확히 밝히세요.