목표
- ViewModel이 만들어진 이유를 이해한다.
ViewModel이 필요한 이유
Android는 모바일 OS 특성상 리소스에 대한 제약이 많은 OS이다. 모바일 OS에서는 리소스를 제거해야만 하게 만드는 제어될 수 없는 이벤트가 발생하게 되는데, Android 프레임워크는 이러한 이벤트가 발생했을 때 Activity와 Fragment 같은 UI 컨트롤러에 대한 제거와 복구를 수행한다.
예를 들어 화면 회전이 이루어진다고 하자. 화면 회전이 이루어지게 되면 Activity가 파괴(onDestroy)된 다음 다시 화면이 만들어지면서(onStart) 복구 로직이(onRestoreInstanceState) 수행된다. Lifecycle에 관한 내용을 모른다면 아래(kotlinworld.com/46) 글을 참조하도록 하자.
Lifecycle에 따라 파괴되고 복구되어야 하는 데이터가 있다면 파괴 전에 데이터를 저장했다가 꺼내와야 하는 번거로움이 있다. 만약 Activity가 살아있는 동안은 계속해서 데이터를 유지할 수 있는 방법이 있다면 굳이 저장 후에 다시 복구하지 않아도 될 것이다. 즉, Activity의 Lifecycle보다 긴 수명을 가지는 인스턴스가 있을 수 있다면 이를 해결할 수 있다.
이러한 점에서 착안해 나온 것이 View(Activity 혹은 Fragment)의 Lifecycle에 맞춰 Model(데이터)를 유지시키는 ViewModel이다. 우리는 Lifecycle의 범위를 Scope라고 표현하는데, ViewModel 인스턴스의 Scope는 ViewModel을 가져올 때 ViewModelProvider에 전달되는 객체의 Lifecycle로 지정된다.
Activity에서의 ViewModel
예를 들어 ViewModelProvider에 다음과 같이 MainActivity가 전달되었다고 해보자. 이 MianViewModel의 데이터는 MainActivity의 Lifecycle을 따른다.
val viewModel = ViewModelProvider(this@MainActivity).get(MainViewModel::class.java)
위의 코드는 아래 그림1과 같은 Scope를 가진다.
Activity의 상태가 변화하던 말던 ViewModel의 데이터는 유지된다. 더 자세히는 Activity가 onDestroy 되든지 onStop되던지 ViewModel 속의 데이터는 유지된다.
그렇다면 언제 ViewModel 속의 데이터가 파괴되는가?
Activity가 더이상 사용하지 않는 상태가 되었을 때(onDestroy 이후 완전히 Finish 되었을 때) ViewModel에서는 onCleared()를 호출하여 내부 데이터(리소스) 초기화를 수행하여 데이터를 파괴한다.
자 이제 이러한 특성을 가진 ViewModel의 역할이 무엇이고 만들어진 목적이 무엇인지 살펴보자.
ViewModel의 역할과 목적
ViewModel의 역할은 View(Activity, Fragment) 상에서 보여주는 데이터를 캡슐화하여 Lifecycle이 변화하여도 데이터를 유지하는 것이다.
안드로이드에서는 Activity의 파괴 시 데이터를 유지하기 위해 saveInstanceState로 표현된 Bundle 인스턴스를 이용하는데 이러한 방식을 이용해 View(UI Controller)단에 데이터를 유지할 경우 유지 보수가 어렵게 될 수 있다. 이를 위해 UI단과 UI단에서 보여주는 데이터의 저장, 처리를 분리하는 것이 권장되는데, 이를 구현한 대표적인 아키텍처가 바로 MVVM 아키텍처 이다.
*MVVM 아키텍처에 대해 잘 모른다면 아래 글을 참조하자.
MVVM 아키텍처에서 View단에 보여줄 데이터의 저장 및 Model단으로의 처리 요청 로직을 포함하는 ViewModel의 역할을 하는 클래스가 바로 ViewModel 클래스이다.
View로부터 View에 표현되는 데이터의 소유권을 분리하는 것이 ViewModel의 주 목적이다.
ViewModel 사용의 장점
이러한 목적을 수행할 수 있게 되면, 다양한 잠점이 생기는데 그 장점은 다음과 같다.
- ViewModel을 이용해 View의 상태 데이터 저장이 용이하다.
- MVVM 아키텍처에서 View Model을 View나 Model과 독립적으로 개발할 수 있다.
- 위의 독립성으로 테스트 가능한 코드를 짤 수 있어 유지 보수가 용이하다.
다음 글에서는 ViewModel을 다루는 다양한 방법에 대해 살펴볼 것이다.