Android (안드로이드)/Lifecycle
Android in A..Z - Lifecycle (ViewModel with SavedStateHandle)
강태종
2021. 3. 20. 01:10
ViewModel with SavedStateHandle
ViewModel은 UI Data를 안전하게 보관하는 방법의 하나입니다. onSavedInstaceState()를 사용하지 않고 데이터를 쉽게 저장/복원 할 수 있고 메모리에 저장하기 때문에 SavedStateHandle에 비해 빠릅니다. 하지만 메모리에 저장하기 때문에 Android Framework에서 메모리를 회수하면 저장된 값을 잃습니다. 하지만 SavedStateHandle은 디스크에 직렬화하여 저장하기 때문에 값을 유지할 수 있습니다.
=> ViewModel에서는 이러한 문제점을 해결하기 위해 SavedStateHandle을 쉽게 조작할 수 있도록 도와줍니다.
ViewModel | SavedInstanceState | Persistent Storage | |
저장소 위치 | 메모리 내 | 디스크에 직렬화 | 디스크 또는 네트워크 내 |
구성 변경 시에도 유지 | 예 | 예 | 예 |
시스템에서 시작된 프로세스 중단 시에도 유지 | 아니요 | 예 | 예 |
사용자의 완전한 활동 닫기/onFinish() 시에도 유지 | 아니요 | 아니요 | 예 |
데이터 제한 | 복잡한 객체도 괜찮지만 사용 가능한 메모리에 의해 공간이 제한됨 | 원시(primitive) 유형 및 문자열과 같은 단순하고 작은 객체만 해당 | 디스크 공간 또는 네트워크 리소스에서 검색하는 비용/시간에 의해서만 제한됨 |
읽기/쓰기 시간 | 빠름(메모리 액세스만) | 느림(직렬화/역직렬화 및 디스크 액세스 필요) | 느림(디스크 액세스 또는 네트워크 트랜잭션 필요) |
Dependency
def lifecycle_version = "2.3.0"
// ViewModel
implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:$lifecycle_version"
implementation "androidx.lifecycle:lifecycle-viewmodel-savedstate:$lifecycle_version"
CounterViewModel
class CounterViewModel(
private val stateHandle: SavedStateHandle,
initialCount: Int = 0
) : ViewModel() {
companion object {
private const val COUNT = "count"
}
val counterLiveData by lazy { stateHandle.getLiveData(COUNT, initialCount) }
fun increase() {
stateHandle[COUNT] = (counterLiveData.value ?: 0) + 1
}
fun reset() {
stateHandle[COUNT] = 0
}
}
CounterViewModelFactory
@Suppress("UNCHECKED_CAST")
class CounterViewModelFactory(
private val initialCount: Int = 0,
owner: SavedStateRegistryOwner,
defaultArgs: Bundle? = null
) : AbstractSavedStateViewModelFactory(owner, defaultArgs) {
override fun <T : ViewModel?> create(key: String, modelClass: Class<T>, handle: SavedStateHandle): T {
return CounterViewModel(handle, initialCount) as T
}
}
CounterFragment
class CounterFragment : BaseFragment<FragmentCounterBinding>(R.layout.fragment_counter) {
private val viewModel by viewModels<CounterViewModel> { CounterViewModelFactory(0, this) }
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
viewModel.counterLiveData.observe(viewLifecycleOwner) {
binding.count = it
}
}
override fun init() {
initSupportActionbar()
initOnCount()
initOnReset()
}
private fun initSupportActionbar() {
setSupportActionBar(binding.toolbar)
}
private fun initOnCount() {
binding.setOnCount {
viewModel.increase()
}
}
private fun initOnReset() {
binding.setOnReset {
viewModel.reset()
}
}
}
ADB Process Kill
adb shell am kill com.taetae98.lifecycle
Git (예제소스)
github.com/KangTaeJong98/Example/tree/main/Android/LifeCycle
KangTaeJong98/Example
My Example Code. Contribute to KangTaeJong98/Example development by creating an account on GitHub.
github.com