안드로이드/공부

안드로이드 라이브데이터(LiveData)

바코더 2020. 4. 30. 13:42

 androidx 부터 도입된 Android Jetpack 에 포함된 LiveData를 공식 developers 사이트를 통해 알아보겠습니다.

사실 프로젝트에 Observer 패턴을 도입하게 되면서 주먹구구 식으로 하다보니 쓰면서도 몬가 이상하다고 느낀적이 많아서, Observer 패턴과 함께 자주 사용되는 LiveData에 대해 공부해보자라는 마음을 먹고 포스팅 하게 되었습니다.

 

https://developer.android.com/topic/libraries/architecture/livedata?hl=ko#work_livedata

 

LiveData 개요  |  Android 개발자  |  Android Developers

LiveData를 사용하여 수명 주기를 인식하는 방식으로 데이터를 처리합니다.

developer.android.com

 LiveData 는 Observer 클래스로 표현되는 관찰자가 Regist 되어있을 때 등록된 Object로 정보를 알리는 역활을 한다고 합니다. 즉 라이프 사이클상태에 따라 정보를 전달하거나 전달하지 않는 유동적인 전달 객체로 사용된다는 거 같네요.

그래서 UI의 라이프 사이클에 때라 정보를 업데이트를 하니 라이프 사이클에 있어서 안정적이고, 자동적으로 메모리 누수도 줄어 들겠죠, 또 오류도 줄어 들것이고요. 

 

그럼 말은 줄이고 빨리빨리 코드를 봐보죠.

public class NameActivity extends AppCompatActivity {

    private NameViewModel model;
    private TextView textView;
    private Button lvDataUpdateBtn;
    String[] stringArray;
    int i;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_name);

        stringArray  = new String[]{"1","2","3"};
        model = new ViewModelProvider(this,getDefaultViewModelProviderFactory()).get(NameViewModel.class);
        textView = findViewById(R.id.viewModelTextView);
        lvDataUpdateBtn = findViewById(R.id.livedata_update_btn);
        lvDataUpdateBtn.setOnClickListener(v->{
            if(i >= stringArray.length)return;
            model.getCurrentName().setValue(stringArray[i]);
            i++;
        });

        final Observer<String> nameObserver = new Observer<String>() {
            @Override
            public void onChanged(String s) {
                textView.setText(s);
            }
        };
        model.getCurrentName().observe(this,nameObserver);
    }
}

 위의 NameActivity에는 2가지 View가 있습니다. Button과 TextView인데, 버튼은 누를때마다 stringArray에 들어있는 String들을 Textview에 차례대로 업데이트 시키는 일을 합니다.

 

그럼 ViewModel 클래스를 보면 

public class NameViewModel extends ViewModel {

    private MutableLiveData<String> currentName;

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

Singleton 형식으로 MutableLiveData를 초기화 하고 있죠. 

 

그런데 이 NameViewModel 을 생성하는 방식이 예제와 조금 다른점이 있습니다. 

 

 // Get the ViewModel.
            model = ViewModelProviders.of(this).get(NameViewModel.class);

 NameViewModel 를 초기화 하는데 있어서 new 나 Sigleton 형식을 쓰는게 아니라 ViewModelProviders로 초기화 시키고 있는데, 위의 코드를 직접 써보면 deprecated 된것을 알 수 있습니다. 

물론 deprecated 된 코드를 써도 되지만, 찝찝해서 찾아본 결과 

 

        model = new ViewModelProvider(this,getDefaultViewModelProviderFactory()).get(NameViewModel.class);

 

ViewModelProviderFactory를 사용하라고 합니다. 굳이 이 ViewModelProviderFactory를 만들 이유가 없을거 같으니 Default로 준비된 팩토리를 사용했습니다.

 

 이제 버튼을 누르면 

 model.currentName.setValue(String) 를 하시면 String이 MutableLiveData에 set이 되고 저희는 

 

model.getCurrentName().observe(this,nameObserver); 코드를 통해 MutableLiveData에 nameObserver를 등록해 놓았기 때문에 Livedata의 값이 변경되면 호출되는 onChaged() 안의 코드가 실행됩니다.

 

 즉 버튼 클릭 -> MutableLiveData.setValue() -> Observer.onChaged()  -> TextView.setText() 의 순서로 값이 전달되어 현재 TextView의 값이 바뀌게 되는 것이죠.

 

아주 기본적인 LiveData와 Observer 구조의 형태를 예제를 통해 보았습니다. 다음에는 조금더 복잡한 예제를 통해 공부해 보겠습니다.