[Android] LiveData

Jay·2021년 1월 14일
0

Android

목록 보기
6/39
post-thumbnail
post-custom-banner

LiveData ⁉️

LiveData is an observable data holder class. Unlike a regular observable, LiveData is lifecycle-aware, meaning it respects the lifecycle of other app components, such as activities, fragments, or services. This awareness ensures LiveData only updates app component observers that are in an active lifecycle state

구글에서 말한 LiveData에 대해 읽어보자.

  1. LiveData is an observable data holder class.

    • 데이터바인딩의 Observable 관련 클래스들과 같이 observable을 관리하는 클래스이다.
  2. Unlike a regular observable, LiveData is lifecycle-aware, meaning it respects the lifecycle of other app components, such as activities, fragments, or services.

    • 일반적인 observable과 달리, LiveData는 액티비티, 프레그먼트, 서비스의 생명주기를 알고 있다.
    • 앱의 다양한 lifecycle에 따른 데이터 관리를 자동으로 해준다.
  3. This awareness ensures LiveData only updates app component observers that are in an active lifecycle state

    • LiveData는 active한 lifecycle 상태에서만 데이터를 업데이트한다.
    • started, resume 상태 등 active할때에만 observe를 업데이트 하기에 뷰가 죽어있는 경우에 대해서 업데이트 하지 않는다.

즉, View의 Lifecycle이 Active한 상태에서만 데이터를 업데이트 시켜주는 Lifecycle-aware Observable data holder class이다.


LiveData 장점

  • UI와 데이터 상태를 일정하게 유지시켜 준다.
    • LiveData는 옵저버 패턴을 따르기에, 옵저버 패턴이 가진 장점도 함께 갖는다.
    • 예를 들어, 옵저버 패턴의 도구들을 사용하지 않는 경우에는 앱의 내 정보에서 프로필 사진을 수정한 경우, 홈에 돌아와서도 프로필 사진을 함께 수정해줘야 한다. 😅 (보통 resume시에 데이터를 업데이트 해준다)
    • 하지만, 옵저버 패턴을 사용하면 자동으로 데이터가 업데이트 되게 이런 코드들은 사라지고 UI는 항상 최신 데이터로 유지가 가능하다. 👍
  • Memory Leak이 없다.
    • LiveData로 observe하는 코드를 만들 때, 사용하는 곳의 Context를 인자로 넘긴다. 이는 Observer가 Lifecycle object와 묶여있다는 것이고, 해당 하는 곳의 Lifecycle이 Destroy된다면 LiveData는 자동으로 자신이 observe한 코드를 없애기에 쓸데없이 유지되는 memory를 남기지 않는다.
  • 데이터를 뿌려줄 액티비티가 사라졌을 때 생기는 앱 crash가 없다.
    • 특정 화면에서 데이터를 받아오는 행위를 비동기 처리한다.
    • 그러다 데이터를 뿌릴 뷰를 찾지만, 사용자가 빠르게 뒤로가거나 홈버튼을 눌러 액티비티가 inactive한 상태가 된 경우, 해당하는 뷰를 찾지 못해 생기는 에러다.
    • LiveData는 Lifecycle을 알고있기에 이러한 inactive 상황에서 데이터를 뿌려주는 행위를 하지 않고, observe한 코드를 삭제하기에 crash가 날 일도 없다. 👀
  • Configuration changes를 적절히 반영한다.
    • 우린 보통 디비이스를 가로, 세로 모드로 바꾸는 경우, 액티비티나 프레그먼트는 다시 그려진다. 이 때에도 LiveData는 데이터를 받아서 자동을 뷰에 뿌려준다.

LiveData with sample code

 private val _movieDetailData = MutableLiveData<MovieDetailResponse>()
    val movieDetailData: LiveData<MovieDetailResponse>
        get() = _movieDetailData

fun getDetailData(movieId : Int){
        addDisposable(movieRepo.getMovieDetail(
            movie_id = movieId,
            apikey = API_KEY,
            language = KR_LANGUAGE,
        )
            .subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe({
                it.run {
                    _movieDetailData.postValue(it)
                }
            },{
                Log.d(TAG, it.localizedMessage)
            })
        )

위는 일종의 예시임으로 보는 것만으로 이해하자.
rx가 들어간 예시이지만 LiveData부분만 보면 되겠다.

MVVM 아키텍처에서 데이터를 받아오고 관리하는 곳으로는 ViewModel이 된다.
그래서 뷰모델에서 LiveData를 선언할때 알아야할 점이 있다.

MutableLiveData와 LiveData의 차이.

  • 이름에서 유추가능하지만 MutableLiveData는 수정가능한 LiveData클래스이다.
    선언된 클래스에서만 데이터를 저장하기 위해 사용 되며 private를 붙여 사용한다.
  • LiveData는 객체 내 데이터 수정이 불가하며 외부에서 접근 하기에 한정자를 붙이지 않는다. 그래서 외부에서 LiveData를 옵저빙할때 get()으로 MutableLiveData를 읽어와서 던져준다.

MutableLiveData와 LiveData를 구분하는 _에 대해선 컨벤션으로 아래 글을 읽어보자.

Names for backing properties
If a class has two properties which are conceptually the same but one is part of a public API and another is an implementation detail, use an underscore as the prefix for the name of the private property

LiveData View 처리

/* observe */
  private fun observeMovieDetailData(){
      viewModel.movieDetailData.observe(this, {
          viewDataBinding.toolbarLayout.title = it.title
          viewDataBinding.contentLayout.apply {
              tvDetailReleaseDate.text = releaseDateParsing(it.release_date)
              tvDetailRuntime.text = runtimeParsing(it.runtime)
              tvDetailGenre.text = genreParsing(it.genres)
              tvDetailOverview.text = it.overview
          }
          intentMovieData = Movie(it.id,it.title,it.overview,it.release_date,it.genres)
      })
  }

위의 코드에서 볼 수 있듯 ViewModel에서 데이터를 observe하고
가져온 데이터에 대해서 처리를 해주고 있다.
위의 예시는 databinding에 값들을 바인딩해주고 있다.


RxJava & LiveData

RxJava가 적용된 프로젝트라면 LiveData 대신 RxJava를 사용할 수도 있다.
LiveData도 RxJava와 유사하게 데이터가 변경 될 경우, Observer에게 데이터 변경을 알려주기에.
하지만, RxJava를 사용할 경우, 앱 수명주기에 맞춰 dispose를 해야하는 불편함이 존재한다.
그와 반대로 LiveData를 사용할 경우, 위에서 말한 LiveData 이점이 있어서 굳이 RxJava로 LiveData를 대체하진 않는다.


Ref

profile
developer
post-custom-banner

0개의 댓글