비즈니스 로직 또는 화면 수준 상태를 유지하기 위한 홀더역할로, UI의 상태를 노출하고, 관련 비즈니스 로직을 캡슐화 할 수 있도록 하는 클래스
화면을 가로 세로 전환하는 경우, 안드로이드는 액티비티를 Destroy 하고 재 생성하게 되는데, 이때 기존 유지하던 데이터가 사라진다.
안드로이드는 onCreate콜백의 savedInstanceState 번들 파미터를 제공하여 개발자가 중요한 데이터는 유지할 수있도록 하고 있긴 하지만, 다음과 같은 문제점이 있다
이런 문제점을 해결하기 위해 데이터를 따로 홀딩하고 있도록 고안된 클래스이다.
ViewModel은 viewModelStoreOwner가 사라질 때 까지 메모리에 남아있다.
ViewModelStoreOwner는 인터페이스로서 Activity와 Fragment가 ViewModelStoreOwner 인터페이스를 구현하고 있다.
따라서 ViewModel은 Activity가 종료되거나, 프래그먼트가 액티비티에서 분리되기 전까지 인스턴스가 유지된다고 할 수 있다.
아래 그림은 ViewModel의 생명주기를 액티비티 생명주기에 빗대어 나타낸 그림이다.
액티비티가 최초 onCreate 호출시 생성되어, 회전시에도 유지가 되고, 액티비티가 더이상 백스택에 남아있을 필요가 없는 finish시에 함께 사라진다.
아래 이미지는 ViewModel을 얻어오는 과정을 나타낸 그림이다.
일반적으로 액티비티에서 뷰모델 클래스를 가져오는 코드는 아래와 같다.
class MainActivity : AppCompatActivity() {
private lateinit var viewModel:MainViewModel
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
//ViewModel 인스턴스 생성
viewModel = ViewModelProvider(this, ViewModelProvider.NewInstanceFactory()).get(MainViewModel::class.java)
}
}
override fun onAttach(context: Context) {
viewModel = ViewModelProvider(requireActivity(), ViewModelProvider.AndroidViewModelFactory.getInstance(requireActivity().application))[YoutubeViewModel::class.java]
super.onAttach(context)
}
뷰 모델은 Context를 소유하지 않는것이 권장된다. 하지만, 그래도 context가 필요한 경우가 있으므로, 이를 위해 애플리케이션 생명주기동안 유효한 applicationContext를 제공해주는 뷰 모델 클래스가 AndroidViewModel 클래스이다. 아래와 같이 사용한다.
viewModel = ViewModelProvider(this, ViewModelProvider.AndroidViewModelFactory(application))
.get(MainViewModel::class.java)
AndroidViewModelFactory를 사용해 생성하는것이 다른점이다.
특히 주의할것은, AndroidViewModel 애플리케이션의 컨텍스트를 제공해 줄 뿐, ViewModelStoreOwner는 동일하게 액티비티/프래그먼트이므로, ViewModelStoreOwner의 라이프사이클에 맞춰 동작한다.
절대로 애플리케이션 전체의 뷰 모델역할을 하는것이 아니다..... 부끄럽다.....
https://todaycode.tistory.com/33
https://kotlinworld.com/79?category=971011
https://charlezz.medium.com/viewmodel%EC%9D%B4%EB%9E%80-%EB%AC%B4%EC%97%87%EC%9D%B8%EA%B0%80-viewmodel-%EC%B4%88%EB%B3%B4%EB%A5%BC-%EC%9C%84%ED%95%9C-%EA%B0%80%EC%9D%B4%EB%93%9C-e1be5dc1ac18