안드로이드

[Android/Kotlin] SharedViewModel (ViewModel을 이용해 데이터 공유)

란서 2022. 2. 24. 16:44

개요

개인 프로젝트 Solaroid  앱 개발을 하면서 프래그먼트간 데이터 공유가 필요한 상황이 발생.
이를 위해 viewModel을 이용한 프래그먼트간 데이터 공유를 사용하였고, 이에 대해 간략하게 정리하고자 한다.


여러 블로그를 돌아본 결과

Koin을 이용한 sharedViewModel, activityViewModel 등 다양한 방법을 이용하여 viewModel내 데이터를 공유하는 모습을 볼 수 있었다.

 

https://developer.android.com/topic/libraries/architecture/viewmodel?hl=ko#sharing 

 

 

ViewModelProvider와 ViewModelStoreOwner 이해

 

우선 나의 경우  ViewModelProvider를 통해 viewModel을 초기화 하고 있다.

viewModelProvider의 생성자는 다음과 같다. 

 

ViewModelProvider의 생성자 매개변수를 살펴보면 ViewModelStoreOwner 타입의 인자를 확인할 수 있다.

실제로 사용할 때는 아무생각없이 "this" 를 넘겨주어  다음과 같이 초기화를 했었는데,

private lateinit var viewModel : tmpViewModel

viewModel = ViewModelProvider(this)[tmpViewModel::class.java]

해당 매개변수는 viewModel을 소유할 UI component (activity or fragment)를 의미한다.

따라서 프래그먼트에서 viewModel을 초기화하면서 this를 넘겨준다면
해당 프래그먼트가 이 viewModel을 소유한다는 의미이다. 

 


그런데 만약 두 개의 프래그먼트(부모-자식 관계가 아닌) 가 있고, 이 두 프래그먼트가 viewModel을 통해 데이터를 공유하려 한다면 위와 같은 상황에서는 같은 viewModel을 받을 수 없다. 각 프래그먼트는 초기화 당시 자기자신을 viewModelStore로 설정했기 때문에 각자 다른 store에서 viewModel을 내주기 때문.

두 프래그먼트가 viewModelStore를 자기자신으로 설정했을 경우


따라서 자신보다 한 계층 위의 UI 컴포넌트(activity 또는 상위 프래그먼트)를 ViewModelStore로 설정하고 viewModel을 초기화한다면 다음과 같이 같은 viewModel을 통해 데이터를 공유할 수 있을 것이다. 

viewModel = ViewModelProvider(this.requireActivity())[tmpViewModel::class.java]

viewModelStore가 한 계층 위 UI 컴포넌트로 설정되어, 하위의 프래그먼트가 같은 viewModel을 공유할 수 있게 된다.

 

 

이 후, viewModel은 Fragment1 과 Fragment2에서 ViewModel 내 데이터를 수정하고, 변경할 수 있으며 viewModel 내 데이터는 activity의 viewModelStore를 통해 서로 공유할 수 있게 됨.