오늘도 더 나은 코드를 작성하였습니까?

LiveData 사용 하기 본문

Android Jetpack Architecture/LiveData

LiveData 사용 하기

hik14 2020. 8. 15. 15:49

-  ViewModel class 내에서 데이터 타입(Generic)을 보유할 LiveData의 객체를 선언한다.

 

-  onChanged() 메서드를 정의하는 Observer 객체를 생성합니다.

onChanged() LiveData 객체가 보유한 데이터 변경 시 호출되어 로직을 처리한다.

일반적으로 Activity fragment와 같은 UI 컨트롤러에 Observer 객체를 생성합니다.

 

- observe() 메서드를 사용하여 LiveData 객체에 Observer 객체를 연결합니다. observe() 메서드는 LifecycleOwner 객체를 사용합니다. 이렇게 하면 Observer 객체가 LiveData 객체를 구독하여 변경사 항에 관한 알림을 받습니다. 일반적으로 Activity fragment와 같은 UI 컨트롤러에 Observer 객체를 연결합니다.

 

ViewModel.LiveData.observe(Activity/fragment(LifecycleOwner), new Observer<type>() {
            @Override
            public void onChanged(String s){
                // 데이터 변경시 로직.
            }
        });

- LiveData를 사용하면 UI 컨트롤러 관찰자가 데이터 변경을 인지 할 수 있다.

LiveData 객체에서 보유한 데이터가 변경되면 응답으로 UI가 자동 업데이트를 할 수 있다.

public class MainActivity extends AppCompatActivity {

    TextView textView;
    TestViewModel testViewModel;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        testViewModel = new ViewModelProvider(this,
                ViewModelProvider.AndroidViewModelFactory
                .getInstance(this.getApplication()))
                .get(TestViewModel.class);

        testViewModel.testStr.observe(this, new Observer<String>() {
            @Override
            public void onChanged(String s) {
                textView.setText(s);
            }
        });

}

LiveData 객체 만들기

- LiveData는 List 등 Collections를 구현하는 객체를 비롯하여 모든 데이터 형태와 함께 사용될 수 있는 래퍼 클래스이다.

- LiveData의 객체는 ViewModel 객체 내에 저장되며 getter 메서드(접근자를 통해) 접근할 수 있다. 

    public class NameViewModel extends ViewModel {

    // Create a LiveData with a String
    private MutableLiveData<String> currentName;

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

    // Rest of the ViewModel...
    }

 

* Activity, Fragment가 아닌 ViewModel 객체에 UI를 업데이트하는 LiveData 객체를 저장해야 되는 이유.

  • Activity, Fragment가 지나치게 커지지 않게 하기 위해서입니다. 이제 이러한 UI 컨트롤러가 데이터의 표시를 담당하지만 데이터 상태를 보유하지 않게 한다.
  • LiveData 인스턴스를 특정 Activity, fragment 인스턴스에서 분리하고 구성 변경(화면 회전)에도LiveData 객체가 유지되도록 하기 위해서입니다.

LiveData 객체 관찰

- Activity, Fragment에서 onCreate() 생명주기 메서드는 LiveData객체를 관찰을 시작하는 좋은 위치인 이유. 

 

1. 시스템이 Activity, Fragment onResume() 메서드에서 중복 호출을 하지 않도록 하기 위해서입니다.

          Activitylifecycle - create - (restart) - start - resume - pause - stop - destroy  

 

2.  Activity, Fragment가 활성 상태(resume - pause)가 되는 즉시 표시할 수 있는 데이터를 보유하도록 하기 위해서입니다. 앱 구성요소는 STARTED 상태가 되는 즉시 관찰하고 있던 LiveData 객체에서 가장 최신 값을 수신합니다.

관찰할 LiveData 객체가 설정된 경우에만 가능하다.

 

* 일반적으로 LiveData는 데이터가 변경될 때만, 그리고 활성 관찰자에게만 업데이트를 전달합니다.

이 동작의 예외로, 관찰자가 비활성 상태에서 활성 상태로 변경될 때에도 관찰자는 업데이트를 받습니다.

관찰자가 비활성 상태에서 활성 상태로 다시 변경되면 마지막으로 활성 상태가 된 이후 값이 변경된 경우에만 업데이트를 받습니다.

LiveData 객체 업데이트

 

LiveData는 안에 있는 데이터를 읽기만 가능하다. 그 안에 데이터를 변경하려면  MutableLiveData 클래스를 이용한다.

 

MutableLiveData 클래스 setValue(T)  postValue(T) 메서드를 공개 메서드로 노출하며 저장된 값을 수정하려면 이러한 메서드를 사용해야 합니다.

MutableLiveData ViewModel에서 사용되며 ViewModel변경이 불가능한 LiveData 객체만 관찰자에게 노출합니다.

 

setValue()는 반드시 메인스레드(UI 스레드)에서만 호출해야된다. 백그라운드에서 호출시 IllegalStateException이 발생한다.

 

postValue()는 주로 백그라운드 스레드에서 호출하는 용도로 사용된다.  변경될 값을 설정하는 태스크를 내부에서 핸들러를 통해 메인스레드로 전달하기 때문이다. 메인 스레드가 실행되기 전에 postValue()를 여러번 호출해도 가장 마지막에 설정된 값을 가져온다.

'Android Jetpack Architecture > LiveData' 카테고리의 다른 글

DataBinding과 LiveData  (0) 2020.08.18
LiveData( MediatorLiveData )  (0) 2020.08.18
LiveData 변환( Transformation class )  (0) 2020.08.17
LiveData 개요와 이점  (0) 2020.08.15