다음과 같이 여러 프래그먼트에서 공통된 관심사의 로직을 수행할때 데이터를 공유하려면 어떻게 해야할까?
(fragment-ktx 라이브러리의 by activityViewModels() Kotlin 속성 위임을 사용)
private val sharedViewModel: OrderViewModel by activityViewModels()
이러한 방법은 Activity의 라이프사이클에 의해 생존주기가 결정되며 해당 액티비티내에서는 같은 데이터를 공유할 수 있다.
하지만 SAA와 같은 한개 또는 적은 수의 액티비티를 구성하는 앱 내에서는 해당 방법은 수많은 뷰모델을 하나의 액티비티에 올려놓기에 적절치 않다.
androidx.navigation.fragment의 2.1.0-alpha02 버전부터 탐색 그래프로 범위가 지정된 ViewModel을 생성하고 그래프 대상 간에 UI 관련 데이터를 공유할 수 있다고 합니다.
이 방식으로 생성된 모든 ViewModel 객체는 연결된 NavHost와 ViewModelStore가 삭제되거나 탐색 그래프가 백 스택에서 소멸되기 전까지 유지됩니다.
val factory: ViewModelProviderFactory = ...
val viewModel: MyViewModel
by navGraphViewModels(R.id.my_graph) { factory }
해당 예시에서는 findNavController()를 자동으로 호출하여 연결된 NavController를 검색한다.
각각의 그래프를 관심사 별로 나누고 거기에 따른 뷰모델 생성 및 소멸이 가능하다!
@HiltViewModel
class ExampleViewModel @Inject constructor(
private val savedStateHandle: SavedStateHandle,
private val repository: ExampleRepository
) : ViewModel() {
...
}
기존의 방법에서 ViewModel에 Hilt 의존성을 주입하면 컴파일에러가 뜨면서 실행이 안된다.
dependencies {
...
implementation 'androidx.hilt:hilt-navigation-fragment:1.0.0'
}
Hilt 라이브러리에서 Jetpack Navigation 라이브러리와의 통합을 지원해준다.
val viewModel: ExampleViewModel by hiltNavGraphViewModels(R.id.my_graph)
사용하는 방법은 기존과 동일하되, hiltNavGraphViewModels로만 바꾸어 사용하면 된다.
참고 자료
https://developer.android.com/codelabs/basic-android-kotlin-training-shared-viewmodel#4
https://developer.android.com/training/dependency-injection/hilt-jetpack?hl=ko