Android Kotlin Fundamentals 05.1: ViewModel and ViewModelFactory 번역 #Summary
- study
- 2019. 11. 29. 22:42
- 안드로이드 앱 아키텍쳐 가이드라인은 각 역할에 맡게 클래스를 분리 하는 것을 추천 합니다.
- UI controller는 액티비티, 프레그먼트와 같은 UI-based의 클래스들 입니다. UI controllers는 UI 관련 로직과 운영체제와 상호작용 하는 로직(사용자의 input 캡쳐와 같은)이 들어 가야 합니다. 이곳에는 데이터들이 포함 되면 안 됩니다. 이러한 데이터는 ViewModel에서 다뤄야 합니다.
- ViewModel은 UI-related data를 저장하고 관리 합니다. ViewModel 클래스는 데이터가 화면 회전고 같은configuration change시 에도 남아 있도록 해줍니다.
- ViewModel은 안드로이드 아키텍쳐 컴포넌트 중 하나 입니다.
- ViewModelProvider.Factory는 뷰모델을 생성하도록 해 주는 인터페이스 입니다.
아래 테이블은 UI controller와 viewModel 인스턴스를 비교 한 것 입니다.
UI controller | ViewModel |
ScoreFragment | ScoreViewModel |
화면에 표시해야 하는 어떠한 데이터도 가지고 있지 않음. | 화면에 표시해야 하는 데이터를 가지고 있음. |
데이터를 표시하는 코드는 가지고 있음 (binding을 이용하여 view에 접근 그리고 데이터를 셋팅 함). 그리고 클릭 리스너와 같이 user-event를 받는 코드를 가지고 있음 | data를 처리하는 코드들을 가지고 있음 |
configuration - change 시 재 생성 됨 | UI controller가 영원히 사라졌을 때 제거 됨 activity가 finish되거나 faragment가 detatch되었을 때 사라짐 |
뷰를 포함 함 | UI controller가 configura-change시 살아남아 있지 않기 때문에, UI controller에 대한 참조를 가지지 않음 |
ViewModel에 대한 참조를 가짐 | View에 대한 참조를 가지지 않음 |
중요한 부분 다시 정리
뷰 모델을 생성 하기 위해서는 ViewModel()을 상속 해야 함.
class GameViewModel : ViewModel() {
init {
Log.i("GameViewModel", "GameViewModel created!")
}
}
onClear는 viewModel 제거되었을 때 호출 됨
override fun onCleared() {
super.onCleared()
Log.i("GameViewModel", "GameViewModel destroyed!")
}
viewModel은 ViewModelProvider를 통해 생성 해야 함.
Log.i("GameFragment", "Called ViewModelProviders.of")
viewModel = ViewModelProviders.of(this).get(GameViewModel::class.java)
ViewModelFactory는 ViewModelProvider.Factory를 상속 해야 함.
class ScoreViewModelFactory(private val finalScore: Int) : ViewModelProvider.Factory {
}
ViewModelFactory는 create 함수를 오버라이드 해야 함
override fun <T : ViewModel?> create(modelClass: Class<T>): T {
if (modelClass.isAssignableFrom(ScoreViewModel::class.java)) {
return ScoreViewModel(finalScore) as T
}
throw IllegalArgumentException("Unknown ViewModel class")
}
ViewModelFactory를 이용해 ViewModel을 생성 하려면 ViewModelProvider에 ViewModelFactory를 넣어 줘야 함
viewModel = ViewModelProviders.of(this, viewModelFactory)
.get(ScoreViewModel::class.java)