안드로이드 앱 개발에 가장 많이 활용되는 Jetpack Component를 꼽으라고 한다면 LiveData는 손에 꼽힐 것이다.
앱 규모가 커지고 복잡해지면서 상태관리가 중요해졌다.
그러다보니 자연스레 MVVM도 표준 아키텍처로 자리잡혔고, 이를 충분히 활용하기 위해 ViewModel과 LiveData가 사용된다.
이번 포스팅 주제로, 안드로이드 프레임워크에서 상태관리를 하기위해 안성맞춤인 LiveData에 대해 자세히 알아본다.
LiveData?
공식 문서에서 소개하는 LiveData를 꼭 읽어보길 바란다.
https://developer.android.com/topic/libraries/architecture/livedata?hl=ko
LiveData에 대해 알기 전에, 안드로이드 앱의 수명주기에 대한 이해도가 필요하다.
안드로이드에서 수명주기는 가장 기본적이고 중요한 개념이다.
Activit, Fragment의 등, 앱 개발 시 사용되는 컴포넌트의 수명주기에 대한 것이다.
안드로이드의 수명주기는 개발자 입장에서 골칫거리다.
Activity, Fragment가 생성/파괴되는 과정, 백그라운드/포그라운드가 전환되는 과정을 생각해보자.
우리는 어떤 작업을 중단하거나 데이터와 UI를 동기화하는 작업이 필요하다.
또한 활성화 중일때도 데이터가 변경되면 UI에 적절하게 반영해야한다.
이런 부분에서 중복되는 코드를 줄이고 고통을 줄이는 방법은 뭘까?
데이터가 변경되거나, 수명주기가 변경되었을 때 적절하게 UI에 알림을 주면 어떨까?
이것을 해결한 것이 바로 LiveData이다.
LiveData를 사용하면 어떤 장점이 있을까?
장점이 많지만, 개인적으로 중요하다고 생각되는 부분만 나열한다.
더욱 많은 장점들에 대해선 공식 문서를 참고하길 바란다.
첫번째, UI와 데이터 상태의 일치 보장
LiveData가 보유한 데이터가 변경될 때, 관찰자에게 알림을 준다.
UI는 데이터가 변경됐을 때 알림을 수신하고 업데이트하면 된다.
데이터 변경 시 여기저기 코드를 추가할 필요 없기 때문에 동기화하기 쉽다.
두번째, 메모리 누수 없음
Observer의 Lifecycle이 종료, 즉 Destory 상태가 되면 자동으로 삭제된다.
즉, 리스너를 삭제한다던가의 부가적인 행위가 필요없다.
세번째, 수명주기를 신경쓰지 않아도 된다.
LiveDat는 Observer의 수명주기에 따라 행동한다.
즉, 활성화 상태인 경우에만 데이터 변경을 호출하고, 파괴된 경우 하지 않는다.
데이터가 변경되어도 앱이 백그라운드에 있거나 UI가 파괴되는 등의 경우에는 알림을 보내지 않는다.
따라서 적절하지 않은 상태에서 UI를 변경한다던가 등으로 인해 앱에 문제가 생기는 일이 없어진다.
또한, 수명주기가 비활성화되었다가 다시 활성화된 경우 최신 데이터에 대해 알림을 보낸다.
즉, 백그라운드에서 포그라운드로 전환되었을 때 onResume에서 UI를 갱신한다던가 등이 필요없다.
LiveData를 글자로 알아보았으니 코드로 알아보자.
먼저 사용을 위해 의존성을 추가해야 한다.
https://developer.android.com/jetpack/androidx/releases/lifecycle?hl=ko 를 참고하자.
dependencies {
def lifecycle_version = "2.5.1"
// ViewModel
implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:$lifecycle_version"
// LiveData
implementation "androidx.lifecycle:lifecycle-livedata-ktx:$lifecycle_version"
}
ViewModel도 함께 사용하기 위해, lifecycle-viewmodel도 추가한다.
lifecycle 패키지엔 이 외에도 다양하므로, 공식 문서를 참고하길 바란다.
우선, 적당한 ViewModel을 생성하고 LiveData를 만들어보자.
class MyViewModel : ViewModel() {
private val _myName: MutableLiveData<String> = MutableLiveData()
val myName: LiveData<String> = _myName
}
여기서 MutableLiveData와 LiveData 두 가지가 사용되었다.
MutableLiveData는 변경 가능한 LiveData이다. 즉, 값의 변경이 가능하다.
MVVM 아키텍처 패턴에서 상태의 변경은 ViewModel 외부에서 불가하다.
따라서 외부 접근을 차단하기 위해private로 선언하고 언더바(_)를 붙여준다.
이를 Backing Property 라고 한다.
LiveData는 Immutable, 즉 변경 불가능하다.
외부에서 오직 값의 변화를 관찰하기 위해 공개되어 있다.
이제 Activity에서 관찰자를 추가해보자.
class NameActivity : AppCompatActivity() {
private val viewModel: NameViewModel by viewModels()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
viewModel.myName.observe(this) {
myNameTextView.text = it
}
}
}
AppCompatActivity는 LifecycleOwner 인터페이스를 구현한다.
따라서 LiveData의 Observer로 등록이 가능하다.
아래는 LiveData의 observe 함수의 구현을 참고하면 좋다.
public abstract class LiveData<T> {
...
@MainThread
public void observe(@NonNull LifecycleOwner owner, @NonNull Observer<? super T> observer) {
assertMainThread("observe");
if (owner.getLifecycle().getCurrentState() == DESTROYED) {
// ignore
return;
}
LifecycleBoundObserver wrapper = new LifecycleBoundObserver(owner, observer);
ObserverWrapper existing = mObservers.putIfAbsent(observer, wrapper);
if (existing != null && !existing.isAttachedTo(owner)) {
throw new IllegalArgumentException("Cannot add the same observer"
+ " with different lifecycles");
}
if (existing != null) {
return;
}
owner.getLifecycle().addObserver(wrapper);
}
...
}
observe 함수의 구현에서 LifecycleOwner의 상태에 따라 어떻게 처리되고 있는지도 확인할 수 있다.
여기까지 LiveData에 대한 개념과 장점, 생성과 관찰자를 등록하는 방법에 대해 알았다.
그럼 LiveData의 값을 어떻게 변화할 수 있을까?
이 부분은 다음 포스팅에서 계속한다.
'개발 > Android' 카테고리의 다른 글
Android - Deep dive into LiveData - 3. Transformations(map, switchMap) (0) | 2023.01.28 |
---|---|
Android - Deep dive into LiveData - 2. setValue vs postValue (0) | 2023.01.21 |
Android - LifecycleOwner vs ViewLifecycleOwner (0) | 2023.01.15 |
[Android] Fragment Lifecycle - onCreateAnimation 은 무엇일까? (0) | 2023.01.14 |
[Android] Clean Architecture With Pokedex (feat. Jetpack Compose, Hilt) - 4 (0) | 2023.01.01 |