ViewModel
2021. 8. 12. 17:46ㆍAndroid/AAC
- ViewModel 이란? 기존 MVVM의 ViewModel 역할(UI에 맞는 데이터 제공) + 수명주기
- ViewModel의 특징
- UI 컨트롤러(activity, fragment, adapter 등)에 대한 context를 참조하면 안됨
- context가 필요한 경우 AndroidViewModel을 이용
- ViewModel을 관리하는 ViewModelStore가 있고, 이를 관리하는 ViewModelStoreOwner가 있음. ViewModelStoreOwner는 ComponentActivity와 Fragment에서 구현하고 있음. 따라서 ViewModel 생성 시 바인딩하는 ViewModelStoreOwner는 Activity나 Fragment가 될 것이고, 이것에 따라 ViewModel의 Scope이 결정됨
- ViewModel 사용법
- build 설정
- ViewModel 클래스 생성
- (파라미터 있는 경우) ViewModelFactory 생성
- UI 컨트롤러에서 참조 생성
1. build 설정
// LiveData와 마찬가지로 프로젝트 생성 시 gradle.properties에 useAndroidX 속성이 true로 설정되며
// 이에 따라 gradle 설정이 자동적으로 진행됨
// 기존 lifecycle-extensions 지원은 중단되었고,
// livedata, viewmodel, lifecycle runtime, viewmodel savedstate로 세분화 되어 지원되고 있음
android.useAndroidX=true
// gradle.build
implementation 'androidx.lifecycle:lifecycle-viewmodel:2.3.1'
2. ViewModel 클래스 생성
// 일반 ViewModel
// 1. No param
class MainViewModel : ViewModel() {}
// 2. param
class CustomViewModel(val param: String) : ViewModel() {}
// context포함 ViewModel(AndroidViewModel 상속)
// 1. No param
class MainViewModel(application: Application) : AndroidViewModel(application) {}
// 2. param
class CustomAndroidViewModel(application: Application, val param: String)
: AndroidViewModel(application) {}
3. (파라미터 있는 경우) ViewModelFactory 생성
// 파라미터 있는 일반 ViewModelFactory
class CustomViewModelFactory(private val param: String) : ViewModelProvider.Factory {
override fun <T : ViewModel?> create(modelClass: Class<T>): T {
return if (modelClass.isAssignableFrom(CustomViewModel::class.java)) {
CustomViewModel(param) as T
} else {
throw IllegalArgumentException()
}
}
}
// 파라미터 있는 context 포함 ViewModelFactory
class CustomAndroidViewModelFactory(private val application: Application, private val param: String)
: ViewModelProvider.NewInstanceFactory() {
override fun <T : ViewModel?> create(modelClass: Class<T>): T {
if (modelClass.isAssignableFrom(AndroidViewModel::class.java)) {
try {
return modelClass.getConstructor(Application::class.java, String::class.java)
.newInstance(application, param)
} catch (e: NoSuchMethodException) {
throw RuntimeException("Cannot create an instance of $modelClass", e)
} catch (e: IllegalAccessException) {
throw RuntimeException("Cannot create an instance of $modelClass", e)
} catch (e: InstantiationException) {
throw RuntimeException("Cannot create an instance of $modelClass", e)
} catch (e: InvocationTargetException) {
throw RuntimeException("Cannot create an instance of $modelClass", e)
}
}
return super.create(modelClass)
}
}
4. UI 컨트롤러에서 참조 생성
// 일반 ViewModel 참조
// 1. No param
// ViewModelFactory에 ViewModelProvider.NewInstanceFactory() 생략 가능(내부 로직에서 반영됨)
val viewModel = ViewModelProivder(this, ViewModelProvider.NewInstanceFactory())
.get(MainViewModel::class.java)
// 2. param
val viewModel = ViewModelProivder(this, CustomFactory(param))
.get(CustomViewModel::class.java)
// context 포함 ViewModel 참조(AndroidViewModelFactory 사용)
// 1. No param
val viewModel = ViewModelProvider(this, ViewModelProvider.AndroidViewModelFactory(application))
.get(MainViewModel::class.java)
// 2. param
val viewModel = ViewModelProivder(this, CustomAndroidFactory(getApplication(), param))
.get(CustomAndroidViewModel::class.java)
// 공식 문서에 .get(modelClass) 대신 [modelClass] 사용되어 있으니 참고
val viewModel = ViewModelProvider(this)[MainViewModel::class.java]
// kotlin의 경우 build 설정 후 아래처럼 쓸 수 있음
implementation "androidx.activity:activity-ktx:1.3.1"
// 1. activity
// Use the 'by viewModels()' Kotlin property delegate from the activity-ktx artifact
val model: MyViewModel by viewModels()
// 2. fragment
// Use the 'by activityViewModels()' Kotlin property delegate from the fragment-ktx artifact
private val model: SharedViewModel by activityViewModels()
공식 레퍼 문서 : https://developer.android.com/reference/androidx/lifecycle/ViewModel
ViewModel | Android 개발자 | Android Developers
ViewModel public abstract class ViewModel extends Object java.lang.Object ↳ androidx.lifecycle.ViewModel Known direct subclasses AndroidViewModel Application context aware ViewModel. ViewModel is a class that is responsible for preparing and mana
developer.android.com
공식 문서 : https://developer.android.com/topic/libraries/architecture/viewmodel?hl=ko
ViewModel 개요 | Android 개발자 | Android Developers
ViewModel을 사용하면 수명 주기를 인식하는 방식으로 UI 데이터를 관리할 수 있습니다.
developer.android.com
'Android > AAC' 카테고리의 다른 글
Jetpack - Compose (0) | 2021.10.28 |
---|---|
Navigation (1) | 2021.08.13 |
DataBinding (1) | 2021.08.13 |
LiveData (0) | 2021.08.12 |
Room (0) | 2021.08.12 |