ViewModel은 생성될 때 전달받은 ViewModelStoreOwner 생애주기를 따라간다.
https://androidhelper.tistory.com/23
[Android] Jetpack ViewModel
ViewModel비즈니스 로직 또는 화면 수준 상태 홀더로,UI 컨트롤러의 데이터를 캡슐화하여 구성 변경이 일어나도 데이터를 유지하는 것이 목적인 구성요소이다. 즉, UI에 상태를 노출하고 관련 비즈
androidhelper.tistory.com
그렇다면 ViewModelStoreOwner 생애주기를 따르는 ViewModel의 생성하려면,
즉, ViewModel의 인스턴스는 어떻게 해야 올바르게 생성해서 사용할 수 있을까?
ViewModelProvider를 사용하는 방법
ViewModelProvider를 사용하여 viewModel 인스턴스를 만들려면 다음과 같이 사용할 수 있다.
viewModel = ViewModelProvider(this).get(MyViewModel::class.java)
ViewModelProvider를 이용하여 ViewModel 인스턴스를 생성할 때 this
즉, Activity(ViewModelStoreOwner)를 전달하였다.
(이 경우에는 Activity에서 this를 호출하였을 경우이다)
class MainActivity : AppCompatActivity() {
private lateinit var viewModel: MyViewModel
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
viewModel = ViewModelProvider(this).get(MyViewModel::class.java)
}
}
ViewModelProvider 통해서 ViewModel의 인스턴스를 가져온 것이다.
그렇다면 viewModelProvider은 어떻게 ViewModel의 인스턴스를 생성하는 것일까?
ViewModelProvider
ViewModelProvider는 다음과 같은 클래스 이다.
public actual open class ViewModelProvider private constructor(
private val impl: ViewModelProviderImpl,
)
앞에서 우리는 ViewModel 인스턴스를 생성하기 위하여
ViewModelProvider의 생성자를 호출하였는데,
우리가 호출한 ViewModelProvider의 생성자는 다음과 같다.
여기서 알 수 있듯이, 특별한 경우가 아닌 경우 DefaultFactory를 제공해주는 것을 확인할 수 있다.
Factory를 통해 ViewModel의 새로운 인스턴스 생성과 관리를 하는 것이다.
ViewModel을 생성하는 Factory에 대해서
좀 더 자세히 알아보자.
우선 factory 객체는 ViewModelProviders에서 메서드를 호출해서 생성하는 것을 확인할 수 있다.
internal object ViewModelProviders
해당 ViewModelProviders object(Singleton)에는 다음과 같은 메서드가 존재한다.
internal fun getDefaultFactory(owner: ViewModelStoreOwner): ViewModelProvider.Factory =
if (owner is HasDefaultViewModelProviderFactory) {
owner.defaultViewModelProviderFactory
} else {
DefaultViewModelProviderFactory
}
여기서 owner가 HasDefaultViewModelProviderFactory일 경우
owner.defaultViewModelProviderFactory를 Facotry로 사용하는 것을 알 수 있다.
그럼 HasDefaultViewModelProviderFactory는 무엇인가?
여기서 ComponentActivity, Fragment를 다시 살펴보면 다음과 같다.
결국 일반적으로 Activity, Fragment (+ NavBackStackEntry)에 의존하는 ViewMoel을 생성할 때
ViewModel를 생성하는 DefaultFactory는
owner의 defaultViewModelProviderFactory를 호출하는 것이다.
그리고 여기서 owner라고 한다면 ComponentActivity, Fragment (+ NavBackStackEntry)가 될 것이고
owner의 defaultViewModelProviderFactory는 다음과 같다.
defaultViewModelProviderFactory
음! 결국 돌고 돌아 ViewModel의 인스턴스를 생성하는 DefaultFactory는
일반적으로 SavedStateViewModelFactory가 되는 것이다.
SavedStateViewModelFactory
ViewModel의 인스턴스를 생성하는 Factory,
SavedStateViewModelFactory는 다음과 같은 class이다.
잠시 앞에 나왔던 내용을 다시 되새기면,
우리는 ViewModel 인스턴스가 어떻게 만들어지는지 알아보던 중
Factory를 통해 ViewModel 인스턴스가 생긴다는 것을 알게 되고,
DefaultFactory가 ViewModelProvider.Factory로 생성된다는 것을 알게 되었으며,
ViewModelProvider에서 Factory, ViewModelProvider.Factory가 무엇인지 알아보고 있는 중이다.
일반적으로 ViewModelProvider에서 getDefaultFactory로 SavedStateViewModelFactory 객체를 불러오는 것을 확인하였다.
그러던 중 SavedStateViewModelFactory라는 구체적인 구현체도 알게 된 것 이다.
🌈 factory의 정체 == SavedStateViewModelFactory
다시 SavedStateViewModelFactory class를 살펴보면 다음과 같다.
@SuppressLint("LambdaLast")
constructor(application: Application?, owner: SavedStateRegistryOwner, defaultArgs: Bundle?) {
savedStateRegistry = owner.savedStateRegistry
lifecycle = owner.lifecycle
this.defaultArgs = defaultArgs
this.application = application
factory = if (application != null) getInstance(application)
else ViewModelProvider.AndroidViewModelFactory()
}
Factory는 다음과 같은 코드로 생성된다.
AndroidViewModelFactory(application)
ViewModelProvider.AndroidViewModelFactory()
JvmViewModelProviders
실제로 ViewModel의 생성은 JvmViewModelProviders에서 담당하는 것을 확인할 수 있다.
참고로 처음에 ViewModel 인스턴스를 가져온 코드에서
viewModel = ViewModelProvider(this).get(MyViewModel::class.java)
ViewModelProvider에서 호출되는 get()을 따라가면 해당 함수를 확인할 수 있다.
해당 로직에서 확인할 수 있는데,
ViewModel을 생성하려고 할 때 인스턴스가 있는지 확인하고
인스턴스가 존재하는 경우 해당 ViewModel을 넘겨주는 것을 확인할 수 있다.
ViewModelProvider와 연관된 범위(일반적으로 fragment이나 Activity)에서 기존 ViewModel을 반환하거나 새 ViewModel을 생성한다.
To Be Continued
- 생성자가 있는 viewModel 생성
- JvmViewModelProviders
- by viewModels(), ktx
- by lazy, 위임 패턴
참고자료
https://developer.android.com/reference/androidx/lifecycle/ViewModelProvider
ViewModelProvider | Android Developers
androidx.appsearch.builtintypes.properties
developer.android.com
'Android > 학습' 카테고리의 다른 글
[Android] Fragment Manager, Basic 편 (1) | 2025.02.16 |
---|---|
[Kotlin] StringBuilder (String 메모리 저장 방식과 StringBuffer를 곁들인..) (0) | 2024.12.12 |
[Android] Jetpack ViewModel (1) | 2024.11.14 |
[Android] Bundle이란? (feat. Activity 간 데이터 전달에 Intent를 사용하는 이유) (0) | 2024.10.01 |
[CS] SOLID - 객체지향 설계의 원칙 (7) | 2024.09.25 |