#1 View Model์ ํ์์ฑ
#1-1 ์์
๋ฒํผ์ ๋๋ฅด๋ฉด TextView์ text๊ฐ 1์ฉ ์ฆ๊ฐํ๋ ์์ ์ฑ์ด๋ค. MainActivity.kt ์ฝ๋๋ ๋ค์๊ณผ ๊ฐ๋ค.
// package com.example.viewmodelbasics
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import androidx.databinding.DataBindingUtil
import com.example.viewmodelbasics.databinding.ActivityMainBinding
class MainActivity : AppCompatActivity() {
private lateinit var binding: ActivityMainBinding
private var count = 0
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = DataBindingUtil.setContentView(this, R.layout.activity_main)
binding.countText.text = count.toString()
binding.countButton.setOnClickListener {
count++
binding.countText.text = count.toString()
}
}
}
#1-2 ๋ฌธ์
์ด ๋, ํ๋ฉด์ ํ์ ์์ผ๋ณด๋ฉด count ์์น๊ฐ ์ด๊ธฐ ์์น์ธ 0์ด ๋์ด๋ฒ๋ฆฐ๋ค. ์๋๋ก์ด๋ ์์คํ
์, ํ๋ฉด ํ์ ๊ณผ ๊ฐ์ ํ๊ฒฝ์ ๋ณํ(configuration change)๊ฐ ์ผ์ด๋๋ฉด Activity๋ฅผ ํ๊ดด(destory)ํ๊ณ ์ฌ์์ฑ(recreate)ํ๋ค. ๊ทธ๋์ MainActivity์ count ๋ณ์ ๋ํ ํ๊ดด๋๊ณ ์ฌ์์ฑ๋ ๊ฒ์ด๋ค.
์๋ฅผ ๋ค์ด REST API๋ก๋ถํฐ ๋ฐ์ดํฐ๋ฅผ ๋ฐ์๋ค์ฌ View์ ํ์ํ๋ ์ด๋ค ์ฑ์ ๊ฐ์ ํด๋ณด์. ํ๋ฉด ํ์ ๋ฑ์ ์ด์ ๋ก Activity๊ฐ ํ๊ดด๋ ํ ์ฌ์์ฑ๋๋ฉด ๊ฐ์ Data๋ฅผ REST API์๊ฒ ์์ฒญํ๋ฉฐ ์์ ๋ญ๋น๋ฅผ ๋ฐ์์ํจ๋ค. ์ฌ์ฉ์ ์
์ฅ์์๋ ๋ฉ์ฉกํ ๋ค์ด๋ก๋ํ๋ Data๊ฐ ๋ ์์์ ๋ ์๊ฐ๊ณ ๋ค์ ๋ค์ด๋ก๋ํ๋ ๊ฑธ ๊ธฐ๋ค๋ ค์ผํ๋ ์ฌ์ฉ์ ๊ฒฝํ๋ ์ ํ๋๋ค. ๋ฐ๋ผ์ ํ์ํ ์๋๋ก์ด๋ ๊ฐ๋ฐ์๊ฐ ๋๊ธฐ ์ํด์ ์ด๋ฌํ configuration change๋ฅผ ๊ณ ๋ คํ ์ค๊ณ๋ฅผ ํ ์ค ์์์ผ ํ๋ค.
#1-3 ViewModel
ViewModel ๊ฐ์ | Android ๊ฐ๋ฐ์ | Android Developers
ViewModel์ ์ฌ์ฉํ๋ฉด ์๋ช ์ฃผ๊ธฐ๋ฅผ ์ธ์ํ๋ ๋ฐฉ์์ผ๋ก UI ๋ฐ์ดํฐ๋ฅผ ๊ด๋ฆฌํ ์ ์์ต๋๋ค.
developer.android.com
์๋๋ก์ด๋ ์ ํธํฉ(JetPack)์ View Model Architecture Component๋ ์ด๋ฌํ ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ ์ ์๋ ์ข์ ์๋จ์ด๋ค. ์ํํธ์จ์ด ๊ฐ๋ฐ์์ View๋ ํ๋ฉด์ ๋ณด์ด๋ UI ๋ถ๋ถ, Model์ ๋ฐ์ดํฐ๋ฅผ ์ฒ๋ฆฌํ๋ ๋ถ๋ถ์ ์๋ฏธํ๋ค. View Model์ด๋, ๋ง ๊ทธ๋๋ก View์ ๊ด๋ จ๋ Model๋ก ์์ ๊ตฌ๊ธ ๊ณต์ ๋ฌธ์์ ๋ฐ๋ฅด๋ฉด, "UI์ ํ์ํ๋ ๋ฐ์ดํฐ๋ฅผ ๋ณด๊ดํ๊ณ ๊ด๋ฆฌ"ํ๋ Model๋ก์ ๋์
๋์๋ค. View Model์ View๊ฐ ์๋ฌด๋ฆฌ ํ๊ดด์ ์ฌ์์ฑ์ ๋ฐ๋ณตํด๋, ๊ทธ ์ํฅ์ ๋ฐ์ง ์๋ ๋ฐ์ดํฐ ๋ณด๊ด์๋ค.
#1-4 ViewModel์ ์๋ช ์ฃผ๊ธฐ
Activity๋ ์๋ช
์ฃผ๊ธฐ๋ ์ ๊ทธ๋ฆผ๊ณผ ๊ฐ์ด ๊ต์ฅํ ์ธ๋ถ์ ์ผ๋ก ๋๋๋ค. ์๊น ์์ ์ฑ์ ํ๋ฉด์ ํ์ ์์ผฐ์ ๋ ํธ์ถ๋์๋ Activity ํด๋์ค์ onDestroy()์ onCreate() ๋ฉ์๋๋ ๋ณด์ธ๋ค. ๋ฐ๋ฉด, ์์ ์๋ View Model์ ์๋ช
์ฃผ๊ธฐ๋ ๊ต์ฅํ ๋จ์ํ๋ค. ์์ฑ ํ ์ํ๋ณํ ์์ด ์ญ ์ด์์๋ค๊ฐ, ๋งจ ๋ง์ง๋ง์ onCleared()๋๋ฉด ๊ทธ์ ์์ผ ๋น๋ก์ ์๋ช
์ฃผ๊ธฐ๊ฐ ๋๋๋ค. onCleared()๊ฐ ๋๋ ์์ ์, ๋ทฐ ๋ชจ๋ธ์ด ๋ ์ด์ ํ์ํ์ง ์์ ์์ ์ผ๋ก ์ฑ์ด ๋ฐฑ๊ทธ๋ผ์ด๋์์ ๋์๊ฐ๋ ์ํฉ์์ ์๋๋ก์ด๋ ์์คํ
์ด ๋ฉ๋ชจ๋ฆฌ๋ฅผ ํ๋ณดํ๊ธฐ ์ํด ํด๋น ์ฑ์ ์ข
๋ฃ์ํฌ ๋๋ฅผ ์๋ก ๋ค ์ ์๋ค. ํน์ ์ฌ์ฉ์๊ฐ ๋ช
์์ ์ผ๋ก ์ฑ์ ์ข
๋ฃ์ํค๊ฑฐ๋, ๋ค๋ก๊ฐ๊ธฐ ๋ฒํผ ๋ฑ์ผ๋ก ์ด์ฉํด Activity์์ ๋ฒ์ด๋ ๋(์๋ฅผ ๋ค์ด, ์นด์นด์คํก ์ผํํ๊ธฐ ์ฐฝ์์ ๋ค๋ก๊ฐ๊ธฐ ๋ฒํผ์ผ๋ก ์นด์นด์คํก ๋ฉ์ธ ํ๋ฉด์ผ๋ก ๋์์์ ๋)๋ค.
์ด์ ๋ถํฐ ์ด View Model์ ํ๋ก์ ํธ์ ์ ๋ชฉ์ํค๋ ๋ฐฉ๋ฒ์ ์์๋ณธ๋ค.
#2 View Model ์ฌ์ฉํ๊ธฐ
#2-1 build.gradle.kts (Module: app)
plugins {
...
}
android {
...
}
dependencies {
val lifecycle_version = "2.5.1"
implementation("androidx.lifecycle:lifecycle-viewmodel-ktx:$lifecycle_version") // ViewModel
...
}
๋จผ์ , ViewModel ํด๋์ค๋ฅผ ๋ถ๋ฌ์ค๊ธฐ ์ํ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ์ถ๊ฐํ๋ค. ๋ชจ๋ ์์ค gradle์ ์์ ๊ฐ์ ๊ตฌ๋ฌธ์ ์ถ๊ฐํ๋ค. ํด๋น ๊ตฌ๋ฌธ์ ์ฌ๊ธฐ์์ ์ถ๋ฆฐ ๊ตฌ๋ฌธ์ด๋ค.
#2-2 MainActivityViewModel.kt
// package com.example.viewmodelbasics
import androidx.lifecycle.ViewModel
class MainActivityViewModel : ViewModel() {
private var count = 0
fun getCurrentCount(): Int {
return count
}
fun getUpdatedCount(): Int {
return ++count
}
}
์ด์ MainActivity์์ View Model๋ก ์ธ MainActivityViewModel๋ฅผ ๋ง๋ ๋ค. ์ด ํด๋์ค๋ ViewModel ํด๋์ค์ ์์์ด๋ฏ๋ก, ViewModel ํด๋์ค๋ฅผ extendsํ๋ค.
MainActivity์ ์๋ count ๋ณ์๋ฅผ MainActivityViewModel๋ก ์ฎ๊ธฐ๊ณ ํด๋น ๋ณ์๋ฅผ ์กฐ์ํ ์ ์๋ ๋ฉ์๋๋ ๋ง๋ ๋ค.
#2-3 MainActivity.kt ์์
// package com.example.viewmodelbasics
...
import androidx.lifecycle.ViewModelProvider
...
class MainActivity : AppCompatActivity() {
...
private lateinit var viewModel: MainActivityViewModel
override fun onCreate(savedInstanceState: Bundle?) {
...
viewModel = ViewModelProvider(this).get(MainActivityViewModel::class.java)
binding.countText.text = viewModel.getCurrentCount().toString()
binding.countButton.setOnClickListener {
binding.countText.text = viewModel.getUpdatedCount().toString()
}
}
}
MainActivityViewModel(View Model)์ ์์ฒด์ ์ธ ์์ฑ์๊ฐ ์์์๋, MainActivity์์ ๊ทธ ์์ฑ์๋ฅผ ํตํด ์ธ์คํด์ค(๊ฐ์ฒด)๋ฅผ ๋ง๋ค์ง ์๋๋ค. ๋์ , ViewModelProvider์ ์์ฑ์๋ฅผ ์ด์ฉํด ์ธ์คํด์ค๋ฅผ ๋ง๋ ๋ค. ์๋ํ๋ฉด ์ผ์ข
์ ์ฑ๊ธํค(์์ฑ์๋ฅผ ํตํด์ ์ฌ๋ฌ ๋ฒ ํธ์ถ์ด ๋๋๋ผ๋ ์ธ์คํด์ค๋ฅผ ์๋ก ์์ฑํ์ง ์๊ณ ์ต์ด ํธ์ถ ์์ ๋ง๋ค์ด๋์๋ ์ธ์คํด์ค๋ฅผ ์ฌํ์ฉ) ๊ฐ๋
์ผ๋ก ViewModel์ ๊ด๋ฆฌํด์ผ๋งํ๊ธฐ ๋๋ฌธ์ด๋ค.์ ๊ทธ๋์ผ๋งํ ๊น? MainActivity๋ ๊ณ์ํด์ ํ๊ดด๋๊ณ ์ฌ์์ฑ๋๋ค๊ณ ํ๋ค. ๊ทธ๋ ๋ค๋ฉด, MainActivity์์ ViewModel์ ์ธ์คํด์ค๋ฅผ ๋ง๋๋ ์ฝ๋๋ ๊ณ์ ์คํ๋๋ค๋ ์๊ธฐ๋ค. ViewModel์ ๋จ์ผ ์ธ์คํด์ค๋ก ์กด์ฌํด์ ์ฌ์ฉ์์๊ฒ ์ผ๊ด๋ UI๋ฅผ ๋ณด์ฌ์ฃผ๊ธฐ ์ํ ๋ชฉ์ ์ ๊ฐ์ง๊ณ ์๋ค. ๊ทธ๋์ ViewModel์ ์ธ์คํด์ค๋ ์ฑ๊ธํค ํจํด์ผ๋ก ๊ด๋ฆฌ๋์ด์ผ ํ๋ค. ๊ทธ๋ฐ๋ฐ ๊ทธ ์ญํ ์ ViewModel์ ์์ฒด ์์ฑ์๋ ์ํํ ์ ์๋ค. ๊ทธ๋์ ViewModelProvider๊ฐ ๋์ ์ํํ๋ ๊ฒ์ด๋ค.
#2-4 ์ฑ ํ ์คํธ
Activity๋ destroy ๋ฐ recreate๋์ง๋ง, ViewModel์ ๊ทธ๋ ์ง ์๊ธฐ ๋๋ฌธ์ count ๋ณ์๊ฐ ๊ณ์ ์ด์์๋ ๋ชจ์ต์ด๋ค.
#3 ์์ฝ
Model์ด '์ฌ๋ฃ'๊ณ View๊ฐ '์๋ฆฌ'๋ผ๋ฉด, View Model์ 'ํ์ํ ์ฌ๋ฃ๊ฐ ์ฌ๋ผ๊ฐ์๋ ๋๋ง'๋ค.
#4 ์์ฑ๋ ์ฑ
android-practice/view-model/ViewModelBasics at master · Kanmanemone/android-practice
Contribute to Kanmanemone/android-practice development by creating an account on GitHub.
github.com
#5 ์ด์ด์ง๋ ๊ธ
[Android] ViewModel - ๋ทฐ ๋ชจ๋ธ์ ์ธ์(Argument) ์ ๋ฌ
#1 ViewModelProvider ํด๋์ค ๋ถ์ #1-1 ์ด์ ๊ธ์ ์์ ์์ [Android] View Model - ๊ธฐ์ด #1 View Model์ ํ์์ฑ#1-1 ์์ ๋ฒํผ์ ๋๋ฅด๋ฉด TextView์ text๊ฐ 1์ฉ ์ฆ๊ฐํ๋ ์์ ์ฑ์ด๋ค. MainActivity.kt ์ฝ๋๋ ๋ค์๊ณผ ๊ฐ๋ค
kenel.tistory.com
ViewModel์ ์ธ์(Argument)๋ฅผ ์ ๋ฌํ๋ ๋ฐฉ๋ฒ์ด๋ค.
'๊นจ์ ๊ฐ๋ ๐ > Android' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
[Android] LiveData - ๊ธฐ์ด (0) | 2024.01.16 |
---|---|
[Android] ViewModel - ๋ทฐ ๋ชจ๋ธ์ ์ธ์(Argument) ์ ๋ฌ (ViewModelFactory) (0) | 2024.01.15 |
[Android] Data Binding - View์ ๊ฐ์ฒด ์ ๋ฌ (0) | 2024.01.12 |
[Android] Data Binding - ๊ธฐ์ด (0) | 2024.01.11 |
AndroidX (๊ตฌ Support Library) (0) | 2023.12.13 |