ViewModel이란?
ViewModel은 비즈니스 로직 또는 화면 수준 상태 홀더이다. UI에 상태를 노출하고 관련 비즈니스 로직을 캡슐화한다.
ViewModel을 사용하게 되면 Activity 간에 이동하거나 화면 전환을 따를 때 UI가 데이터를 다시 가져올 필요가 없다.
이러한 ViewModel은 위 클래스를 사용하지 않고, 일반 클래스로도 구현이 가능하다. 그러나 이는 Activity와 탐색 대상 간에 이동할 때 문제가 될 수 있다. 인스턴스 상태 저장 메커니즘을 사용하여 데이터를 저장하지 않을 경우 해당 데이터가 소멸된다. 이러한 점을 해결하기 위해 ViewModel은 데이터 지속성을 위한 편리한 API를 제공한다.
ViewModel의 이점
- UI 상태를 유지할 수 있다.
- 비즈니스 로직에 대한 액세스 권한을 제공한다.
- 안드로이드의 생명 주기를 관리하기 쉽다.
- UI 컨트롤러(Activity, Fragment 등)에서 모든 것을 다 처리하려고 하면 코드가 복잡해지기 때문에 ViewModel을 사용하여 분리하면 테스트나 유지보수에 용이하다.
ViewModel의 LifeCycle
ViewModel의 생명 주기는 범위와 직접 연결된다. ViewModel은 범위로 지정된 ViewModelStoreOwner가 사라질 때까지 메모리에 남아있다. ViewModelStoreOwner는 아래의 경우에서 발생한다.
- Activity가 완료될 때
- Fragment가 분리될 때
- Navigation의 경우 백 스택에서 제거될 때
따라서, ViewModel은 구성 변경 후에도 유지되는 데이터를 저장하기 위한 좋은 수단이다.
ViewModel은 Activity가 더 이상 사용하지 않는 상태가 되었을 때(onDestroy) ViewModel에서 onCleared()를 호출하여 데이터 초기화를 수행하여 데이터를 지운다.
코드 샘플
ViewModel 클래스 생성
import androidx.lifecycle.ViewModel
// ViewModel에서 변수하나만 만들어서 사용하지는 않고, LiveData 등을 이용해서 함께 사용하는 경우가 많음
class MainViewModel : ViewModel() {
var countValue = 0
fun plus() {
countValue++
}
fun minus() {
countValue--
}
fun getCount() : Int {
return countValue
}
}
Main에서 호출
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.widget.Button
import android.widget.TextView
import androidx.lifecycle.ViewModelProvider
class MainActivity : AppCompatActivity() {
//private var count = 0
lateinit var viewModel: MainViewModel
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
viewModel = ViewModelProvider(this).get(MainViewModel::class.java)
val plusBtn = findViewById<Button>(R.id.btnPlus)
val minusBtn = findViewById<Button>(R.id.btnMinus)
val resultText = findViewById<TextView>(R.id.resultText)
resultText.text = viewModel.countValue.toString()
plusBtn.setOnClickListener {
viewModel.plus()
resultText.text = viewModel.countValue.toString()
//count++
//resultText.text = count.toString()
}
minusBtn.setOnClickListener {
viewModel.minus()
resultText.text = viewModel.countValue.toString()
//count--
//resultText.text = count.toString()
}
}
}
마무리
오늘은 ViewModel에 관해 간단하게 정리해 보았다. 위의 예시는 정말 간단한 예시를 작성해둔 것이고, 실제로 ViewModel은 LiveData, Coroutines 등과 함께 쓰이는 경우가 많다.
요즘 많이 사용하는 디자인 패턴 MVVM(Model-View-ViewModel)에서 View나 Model과 독립적으로 개발할 수도 있고, 열심히 학습한다면 앞으로 개발에 유용하게 쓰일 것 같다.
LiveData와 Coroutines를 학습한 뒤 ViewModel과 적용하여 코드를 구현해볼 계획이다.
참고
ViewModel 개요 | Android 개발자 | Android Developers
ViewModel을 사용하면 수명 주기를 인식하는 방식으로 UI 데이터를 관리할 수 있습니다.
developer.android.com