[안드로이드] LiveData 란

jetpack의 구성요소

데이터를 담아둘 수 있는 데이터 홀더 클래스로, 다른 클래스와 달리 액티비티, 프래그먼트, 서비스 들의 수명주기를 고려합니다.

이때, 활성 수명주기(start or resume)에 있는 구성요소만 관련 데이터를 업데이트합니다.

왜 LiveData를 쓸까

#### 1. UI와 데이터 상태의 일치 보장

livedata는 관찰자 패턴을 따릅니다. 구성요소의 수명주기가 변경될 때마다 Observer 객체에 알립니다. 
따라서 이러한 Observer 객체(주로 ui 구성요소)에 UI를 업데이트 할 수 있습니다.

#### 2. 최신 데이터 유지

수명 주기가 비활성화되면 다시 활성화될 때 최신 데이터를 수신합니다. 
예를 들어 백그라운드에 있었던 활동은 포그라운드로 돌아온 직후 최신 데이터를 받습니다  

#### 3. 수명 주기를 더 이상 수동으로 처리하지 않음

UI 구성요소는 관련 데이터를 관찰하기만 할 뿐 관찰을 중지하거나 다시 시작하지 않습니다. 
LiveData는 관찰하는 동안 관련 수명 주기 상태의 변경을 인식하므로 이 모든 것을 자동으로 관리합니다.

사용 방법

LiveData는 List와 같은 Collections를 구현하는 객체를 비롯하여 모든 데이터와 함께 사용할 수 있는 래퍼입니다.

LiveData 객체는 일반적으로 ViewModel 객체 내에 저장되며 다음 예에서 보는 것과 같이 getter 메서드를 통해 액세스됩니다.

     public class NameViewModel extends ViewModel {

        //MutableLiveData란 변경할 수 있는 LiveData 형입니다.    
        //그냥 LiveData는 변경불가능함!
        private MutableLiveData<String> currentName;

        public MutableLiveData<String> getCurrentName() {
            if (currentName == null) {
                currentName = new MutableLiveData<String>();
            }
            return currentName;
        }

    // Rest of the ViewModel...
    }

대부분의 경우 앱 구성요소의 onCreate() 메서드는 LiveData 객체 관찰을 시작하기 적합한 장소이며 그 이유는 다음과 같습니다.

1. 시스템이 액티비티나 프래그먼트의 onResume() 메서드에서 중복 호출을 하지 않도록 하기 위해서입니다.
  
2. 액티비티 또는 프래그먼트가 활성 상태가 되는 즉시 표시할 수 있는 데이터를 보유하도록 하기 위해서입니다. 

다음은 액티비티에서 뷰모델을 생성해 LiveData를 관찰하도록 하는 과정입니다.

   public class NameActivity extends AppCompatActivity {

        private NameViewModel model;

        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);

            // Other code to setup the activity...

            // 뷰모델을 생성합니다.
            model = new ViewModelProvider(this).get(NameViewModel.class);

            // 관찰자를 생성하도록 함.
            final Observer<String> nameObserver = new Observer<String>() {
                @Override
                public void onChanged(@Nullable final String newName) {
                
                    // ui를 갱신하는 코드
                    nameTextView.setText(newName);
                }
            };

            // 옵저버를 넘겨 뷰모델을 관찰할 수 있도록 합니다.
            model.getCurrentName().observe(this, nameObserver);
        }
    }
    

버튼 클릭으로 LiveData 갱신하는 예제

  // setValue 메서드 호출로 인해 Observer의 onChange 메서드가 호출되어 관련 ui가 갱신된다.
   button.setOnClickListener(new OnClickListener() {
        @Override
        public void onClick(View v) {
            String anotherName = "John Doe";
            model.getCurrentName().setValue(anotherName);
        }
    });

#### ※ 기본 스레드에서 LiveData 객체를 업데이트하려면 setValue(T) 메서드를 호출해야 합니다. #### 코드가 작업자 스레드에서 실행된다면 대신 postValue(T) 메서드를 사용하여 LiveData 객체를 업데이트할 수 있습니다.