#1 ViewModelProvider ํด๋์ค ๋ถ์
#1-1 ์์ ํ ์ํ ์ฑ
[Android] View Model - ๊ธฐ์ด
#1 View Model์ ํ์์ฑ#1-1 ์์ ๋ฒํผ์ ๋๋ฅด๋ฉด TextView์ text๊ฐ 1์ฉ ์ฆ๊ฐํ๋ ์์ ์ฑ์ด๋ค. MainActivity.kt ์ฝ๋๋ ๋ค์๊ณผ ๊ฐ๋ค. // package com.example.viewmodelbasics import androidx.appcompat.app.AppCompatActivity import andro
kenel.tistory.com
์ ๊ฒ์๊ธ์ '์์ฑ๋ ์ฑ'์ ์์ ํด์, ViewModel ํด๋์ค๊ฐ ์ธ์(Argument)๋ฅผ ๋ฐ๊ฒ ๋ง๋ค์ด๋ณธ๋ค.
๊ทธ๋ฅ class sampleViewModel(args: Int) : ViewModel() { ... }์ ๊ฐ์ด ์ธ์๋ฅผ ๋ฐ๋ ViewModel ํด๋์ค๋ฅผ ๋ง๋ค์ด ์ฐ๋ฉด ๊ทธ๋ง ์๋๋๋ ์๊ฐ๋ ๋ ๋ค. ํ์ง๋ง ์ด์ ๊ธ์ ๋ฐ๋ฅด๋ฉด View Model์ ์ธ์คํด์ค๋ View Model์ ์์ฒด ์์ฑ์๊ฐ ์๋๋ผ, ViewModelProvier์ ์์ฑ์๋ฅผ ์ด์ฉํ ๊ฐ์ ์ ์ธ ๋ฐฉ๋ฒ์ผ๋ก ์์ฑ๋๋ค. ๋จผ์ , ๊ทธ ๋ฐฉ๋ฒ์ด๋ผ๋ ๊ฒ์ ์์ธํ ์ดํด๋ณธ๋ค.
#1-2 ViewModelProvider์ ์์ฑ์ ์ดํด๋ณด๊ธฐ
...
public open class ViewModelProvider
/**
* Creates a ViewModelProvider
* Params:
* store - `ViewModelStore` where ViewModels will be stored.
* factory - factory a `Factory` which will be used to instantiate new `ViewModels`
* defaultCreationExtras - extras to pass to a factory
*/
constructor(
private val store: ViewModelStore,
private val factory: Factory,
private val defaultCreationExtras: CreationExtras = CreationExtras.Empty,
) {
...
/**
* Creates ViewModelProvider. This will create ViewModels and retain them in a store of the given ViewModelStoreOwner.
* This method will use the default factory if the owner implements HasDefaultViewModelProviderFactory. Otherwise, a NewInstanceFactory will be used.
*/
public constructor(
owner: ViewModelStoreOwner
) : this(owner.viewModelStore, defaultFactory(owner), defaultCreationExtras(owner))
/**
* Creates ViewModelProvider, which will create ViewModels via the given Factory and retain them in a store of the given ViewModelStoreOwner.
* Params:
* owner - a ViewModelStoreOwner whose ViewModelStore will be used to retain ViewModels
* factory - a Factory which will be used to instantiate new ViewModels
*/
public constructor(owner: ViewModelStoreOwner, factory: Factory) : this(
owner.viewModelStore,
factory,
defaultCreationExtras(owner)
)
...
public interface Factory {
...
}
public companion object {
internal fun defaultFactory(owner: ViewModelStoreOwner): Factory = ...
...
}
}
internal fun defaultCreationExtras(owner: ViewModelStoreOwner): CreationExtras {
...
}
...
์ด 3๊ฐ์ ์์ฑ์๊ฐ ๋ณด์ธ๋ค. ๋งจ ์์ ๊ธฐ๋ณธ ์์ฑ์๊ฐ ์๋ค. ๊ธฐ๋ณธ ์์ฑ์๊ฐ ์๊ตฌํ๋ ์ธ์๋ 3๊ฐ์ง๋ก ์ฒซ์งธ๋ ViewModelStore, ๋์งธ๋ ViewModelProvider ํด๋์ค ๋ด๋ถ์ ์ ์๋ ์ธํฐํ์ด์ค์ธ ViewModelProvider.Factory, ์ ์งธ๋ CreationExtras์ด๋ค.
๊ธฐ๋ณธ ์์ฑ์ ๋ค์, ๋ณด์กฐ ์์ฑ์์ธ 2๋ฒ์งธ ์์ฑ์, 3๋ฒ์งธ ์์ฑ์๋ ์๋ค. '2๋ฒ์งธ ์์ฑ์'๊ฐ ์ด์ ๊ธ์์ ์ฌ์ฉํ๋ ์์ฑ์๋ค. '2๋ฒ์งธ ์์ฑ์'๋ ViewModelStore๋ง ์ธ์๋ก ๋ฐ๊ณ ๋๋จธ์ง๋ ๊ธฐ๋ณธ๊ฐ(๊ฐ๊ฐ ํจ์ defaultFactory(), defaultCreationExtras())์ผ๋ก ์ฒ๋ฆฌํ๋ค. '3๋ฒ์งธ ์์ฑ์'๋ ViewModelStore์ ViewModelProvider.Factory๋ฅผ ์ธ์๋ก ๋ฐ๊ณ CreationExtras๋ง ๊ธฐ๋ณธ๊ฐ์ผ๋ก ์ฒ๋ฆฌํ๋ค.
์ด๋ ์์ฑ์๋ ๊ฐ์ ViewModelProvider.Factory ํด๋์ค๊ฐ ๋์จ๋ค. ViewModelProvider.Factory๋ ํฉํ ๋ฆฌ ๋ฉ์๋ ํจํด(Factory Method Pattern)์ ๊ตฌํํ๊ธฐ ์ํ ํด๋์ค๋ค. ์ฆ, ViewModelProvider๋ ํฉํ ๋ฆฌ ๋ฉ์๋ ํจํด์ผ๋ก ViewModel ํด๋์ค์ ์ธ์คํด์ค๋ฅผ ์์ฑํ๊ณ ์๋ค.
๋ฐ๋ผ์, defaultFactory() ๋์ ๋ด๊ฐ ์ง์ ViewModelProvider.Factory์ ๊ตฌํ ํด๋์ค๋ฅผ ๋ง๋ค ์ ์๋ค๋ฉด, ์ด์ ๊ธ์ ์ฝ๋๋ฅผ '3๋ฒ์งธ ์์ฑ์'๋ฅผ ์ด์ฉํด ๋ค์ ์งค ์ ์๋ค.
#2 '2๋ฒ์งธ ์์ฑ์' ๋์ '3๋ฒ์งธ ์์ฑ์' ์ฌ์ฉํ๊ธฐ
#2-1 MainActivityViewModelFactory.kt ๋ง๋ค๊ธฐ
// package com.example.argumenttoviewmodel
import androidx.lifecycle.ViewModel
import androidx.lifecycle.ViewModelProvider
class MainActivityViewModelFactory : ViewModelProvider.Factory {
override fun <T : ViewModel> create(modelClass: Class<T>): T {
if (modelClass.isAssignableFrom(MainActivityViewModel::class.java)) {
return MainActivityViewModel() as T
}
throw IllegalArgumentException("Unknown View Model Class")
}
}
defaultFactory๋ฅผ ๋์ ํ custom(์ฌ์ฉ์ ์ ์) ํด๋์ค๋ฅผ ๋ง๋ ๋ค. ์ด ํด๋์ค๋ ์ธํฐํ์ด์ค ViewModelProvider.Factory์ ๊ตฌํ ํด๋์ค๋ค. create()๋ฅผ overrideํ๊ณ ์์ ๊ฐ์ด ์ฝ๋๋ฅผ ์ง ๋ค. ์ด๋ ๊ฑฐ์ ๋ชจ๋ ViewModelProvider.Factory์ ๊ตฌํ ํด๋์ค์์ ์ฌ์ฉํ๋ ํ์ค๊ณผ๋ ๊ฐ์ ์์ฉ๊ตฌ ์ฝ๋๋ผ๊ณ ํ๋ค. ํ๋ก๊ทธ๋๋จธ๊ฐ '2๋ฒ์งธ ์์ฑ์'๋ฅผ ์ฐ๋ ๊ฒฝ์ฐ, ViewModelProvider๋ ์ด ๊ตฌํ ํด๋์ค์ ๊ฐ์ ๊ธฐ๋ฅ์ ํ๋ defaultFactory()๋ฅผ ์์์ ๋ง๋ค์ด ์ ๊ณตํ๋ ๊ฒ์ด๋ค.
#2-2 MainActivity.kt ์์
...
class MainActivity : AppCompatActivity() {
...
private lateinit var viewModelFactory: MainActivityViewModelFactory
...
override fun onCreate(savedInstanceState: Bundle?) {
...
viewModelFactory = MainActivityViewModelFactory()
viewModel = ViewModelProvider(this, viewModelFactory).get(MainActivityViewModel::class.java) // '3๋ฒ์งธ ์์ฑ์' ์ฌ์ฉ
...
}
}
MainActivity.kt๋ฅผ ์์ ํด, MainActivityViewModelFactory์ ์ธ์คํด์ค๋ฅผ ๋ง๋ค๊ณ '2๋ฒ์งธ ์์ฑ์' ๋์ '3๋ฒ์ ์์ฑ์'๋ฅผ ์ฌ์ฉํด ViewModel์ ์ธ์คํด์ค๋ฅผ ๋ง๋ ๋ค. ๋๋จธ์ง ์ฝ๋๋ ์ ์งํ๋ค.
#2-3 ๊ตฌ๋ ํ ์คํธ

์ด์ ๊ณผ ๋๊ฐ์ด ์ ์๋ํ๋ค.
#3 ViewModel ๊ฐ์ฒด์ ์ธ์ ์ ๋ฌํ๊ธฐ
์ฌ์ค ์ด๋ฏธ #2์์ ๋ต์ด ๋์๋ค. MainActivityViewModelFactory ํด๋์ค๊ฐ ์ธ์๋ฅผ ๋ฐ๋๋ก ์์ ํ๋ฉด ๋์ด๋ค. ์ผ๊ฐ์์ ์ธ์๋ฅผ ์ ๋ฌํ ๋๋ง ์ปค์คํ
ํฉํ ๋ฆฌ๋ฅผ ๋ง๋ ๋ค๋ผ๊ณ ํ๋๋ฐ, ์ด๋ ์๋ฐํ๊ฒ๋ ๋
ผ๋ฆฌ์ ์ผ๋ก ํ๋ฆฐ ๋ง์ด๋ค. #2์์ ์ธ์๊ฐ ์์ด๋ ์ปค์คํ
ํฉํ ๋ฆฌ๋ก ๋ง๋ค์์์ ๋ณด์ด์ง ์์๋๊ฐ. ๋ฐ๋ผ์, ๋ง์ ๊น๊นํ๊ฒ ๊ณ ์น๋ฉด ๋ค์๊ณผ ๊ฐ๋ค. ViewModel์ ์ธ์๋ฅผ ์ ๋ฌํ์ง ์์๊ฑฐ๋ผ๋ฉด '๊ตณ์ด' ์ปค์คํ
ํฉํ ๋ฆฌ๋ฅผ ๋ง๋ค 'ํ์'๊ฐ ์๋ค.
ViewModel์ ์ธ์๋ฅผ ์ ๋ฌํ๋ ์ฝ๋๋ ๋ค์๊ณผ ๊ฐ๋ค.
#3-1 MainActivityViewModel.kt ์์
...
class MainActivityViewModel(startingCount : Int) : ViewModel() {
private var count = 0
init {
count = startingCount
}
...
}
init { ... } ๋ธ๋ก์ ์ฐ์ง ์๊ณ , private var count = startingCount ์ ๊ฐ์ด ์ฝ๋๋ฅผ ์ง๋ ๋๋ค. ํน์, init { ... } ๋ธ๋ก๊ณผ private var count = 0 ๋๋ค ์์ ๋ฒ๋ฆฌ๊ณ , class ์ ์ธ๋ถ์ class MainActivityViewModel(private var count : Int) : ViewModel()๊ณผ ๊ฐ์ด ์ ์ด๋ ๋๋ค.
#3-2 MainActivityViewModelFactory.kt ์์
...
class MainActivityViewModelFactory(private val startingCount: Int) : ViewModelProvider.Factory {
override fun <T : ViewModel> create(modelClass: Class<T>): T {
if (modelClass.isAssignableFrom(MainActivityViewModel::class.java)) {
return MainActivityViewModel(startingCount) as T
}
throw IllegalArgumentException("Unknown View Model Class")
}
}
#3-3 MainActivity.kt ์์
...
class MainActivity : AppCompatActivity() {
...
override fun onCreate(savedInstanceState: Bundle?) {
...
viewModelFactory = MainActivityViewModelFactory(777)
...
}
}
MainActivityViewModel.count์ 777์ ์ ๋ฌํ๋ค.
#3-4 ๊ตฌ๋ ํ ์คํธ

#4 ์์ฝ
ViewModel์ ์์ฑ์๊ฐ ํน์ดํ ํํ์ธ ์ด์ ๋ ํฉํ ๋ฆฌ ๋ฉ์๋ ํจํด์ ๊ตฌํํ๊ธฐ ์ํด์๋ค.
#5 ์์ฑ๋ ์ฑ
android-practice/view-model/ArgumentToViewModel at master ยท Kanmanemone/android-practice
Contribute to Kanmanemone/android-practice development by creating an account on GitHub.
github.com
'๊นจ์ ๊ฐ๋ ๐ > Android' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
[Android] ViewModel - View์ ๊ฐ์ฒด(ViewModel) ์ ๋ฌ (0) | 2024.01.18 |
---|---|
[Android] LiveData - ๊ธฐ์ด (0) | 2024.01.16 |
[Android] ViewModel - ๊ธฐ์ด (0) | 2024.01.13 |
[Android] Data Binding - View์ ๊ฐ์ฒด ์ ๋ฌ (0) | 2024.01.12 |
[Android] Data Binding - ๊ธฐ์ด (0) | 2024.01.11 |