ViewModel

Lifecycle-aware component

ViewModel ์ด๋ž€

์•ˆ๋“œ๋กœ์ด๋“œ ํ”„๋ ˆ์ž„์›Œํฌ๋Š” Activity / Fragment ์™€ ๊ฐ™์€ UI ์ปจํŠธ๋กค๋Ÿฌ์˜ ์ˆ˜๋ช… ์ฃผ๊ธฐ๋ฅผ ๊ด€๋ฆฌํ•œ๋‹ค.

์‹œ์Šคํ…œ์—์„œ UI ์ปจํŠธ๋กค๋Ÿฌ๋ฅผ ์ œ๊ฑฐํ•˜๊ฑฐ๋‚˜ ๋‹ค์‹œ ๋งŒ๋“œ๋Š” ๊ฒฝ์šฐ, ์ปจํŠธ๋กค๋Ÿฌ์— ์ €์žฅ๋œ ๋ชจ๋“  UI ๊ด€๋ จ ๋ฐ์ดํ„ฐ๊ฐ€ ์‚ญ์ œ๋œ๋‹ค. ๋””๋ฐ”์ด์Šค ํ™”๋ฉด ํšŒ์ „ํ•˜๋Š” ๊ฒฝ์šฐ ์œ„์™€ ๊ฐ™์ด ์ปจํŠธ๋กค๋Ÿฌ๋ฅผ ์ œ๊ฑฐํ•œ ํ›„ ์ƒˆ๋กœ ์ƒ์„ฑ์„ ํ•œ๋‹ค. ๋‹จ์ˆœํ•œ ๋ฐ์ดํ„ฐ๋ฅผ ๋ณต์›ํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” onSaveInstanceState() ๋ฉ”์„œ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ onCreate() ํ˜ธ์ถœ ์‹œ ๋ฐ์ดํ„ฐ๋ฅผ ๋ณต์›ํ•  ์ˆ˜ ์žˆ๋‹ค. ํ•˜์ง€๋งŒ ์ด ๋ฐฉ๋ฒ•์€ ์†Œ๋Ÿ‰์˜ ๋ฐ์ดํ„ฐ์—๋งŒ ์ ํ•ฉํ•˜๋‹ค.

ViewModel ๊ฐ์ฒด๋Š” ์ด๋Ÿฌํ•œ ์ƒํ™ฉ์—์„œ ์ž๋™์œผ๋กœ ๋ณด๊ด€๋˜์–ด ์•กํ‹ฐ๋น„ํ‹ฐ / ํ”„๋ž˜๊ทธ๋จผํŠธ ์ธ์Šคํ„ด์Šค์—์„œ ์ฆ‰์‹œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.

๊ตฌํ˜„

class MainViewModel : ViewModel() {

    private val _todo: MutableLiveData<String> = MutableLiveData("init")
    val todo: LiveData<String>
        get() = _todo
    
}
class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        
        // ์ดˆ๊ธฐํ™” ๋ฐฉ๋ฒ• 1
        val viewModel: MainViewModel by viewModels()
        // ์ดˆ๊ธฐํ™” ๋ฐฉ๋ฒ• 2
        val viewModel2 by lazy { ViewModelProvider(this)[MainViewModel::class.java] }

        viewModel.todo.observe(this) { value ->
            Toast.makeText(this, "value : $value", Toast.LENGTH_SHORT).show()
        }
    }
}

์œ„์— ์ฝ”๋“œ์™€ ๊ฐ™์ด ๋ทฐ๋ชจ๋ธ ํด๋ž˜์Šค๋Š” Jetpack์—์„œ ์ œ๊ณตํ•˜๋Š” ViewModel ์„ ์ƒ์†ํ•˜์—ฌ ๋งŒ๋“ค ์ˆ˜ ์žˆ๊ณ , ์•กํ‹ฐ๋น„ํ‹ฐ๋‚˜ ํ”„๋ž˜๊ทธ๋จผํŠธ์—์„œ ๊ฐ์ฒด์ƒ์„ฑํ•˜์—ฌ ์‚ฌ์šฉํ•  ์ˆ˜์žˆ๋‹ค.

์ƒ๋ช…์ฃผ๊ธฐ

ViewModel ์€ LifecycleOwners ์˜ ํŠน์ • ์ธ์Šคํ„ด์Šคํ™”๋ณด๋‹ค ์˜ค๋ž˜ ์ง€์†๋˜๋„๋ก ์„ค๊ณ„๋˜์–ด์žˆ๋‹ค. ๋ทฐ๋ชจ๋ธ ๊ฐ์ฒด์—๋Š” View, Activity, Fragment ๊ฐ์ฒด๋‚˜ Context๋ฅผ ์ฐธ์กฐํ•˜๋ฉด ์•ˆ๋œ๋‹ค. (๋ทฐ๋ชจ๋ธ์˜ ๋ผ์ดํ”Œ์‚ฌ์ดํด์€ UI ๋ผ์ดํ”Œ์‚ฌ์ดํด๋ณด๋‹ค ์˜ค๋ž˜ ์ง€์†๋˜๊ธฐ ๋•Œ๋ฌธ์— onCleared() ํ•จ์ˆ˜๊ฐ€ ํ˜ธ์ถœ๋˜๊ธฐ ์ „, UI ์™€ ๊ด€๋ จ ๊ฐ์ฒด๋‚˜ Context ๋ฅผ ์ฐธ์กฐํ•˜๊ฒŒ ๋˜๋ฉด GC์—์„œ ์ˆ˜๊ฑฐํ•˜์ง€ ๋ชปํ•ด, ๋ฉ”๋ชจ๋ฆฌ ๋ˆ„์ˆ˜๊ฐ€ ๋ฐœ์ƒํ•œ๋‹ค)

์‹œ์Šคํ…œ ์„œ๋น„์Šค๋ฅผ ์ฐพ๋Š”๋ฐ ApplicationContext ๊ฐ€ ํ•„์š”ํ•œ ๊ฒฝ์šฐ์—๋Š” AndroidViewModel ํด๋ž˜์Šค๋ฅผ ํ™•์žฅํ•˜์—ฌ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค. ViewModel ๊ฐ์ฒด์˜ ๋ฒ”์œ„๋Š” ViewModel ์„ ๊ฐ€์ ธ์˜ฌ ๋•Œ ViewModelProvider ์— ์ „๋‹ฌ๋˜๋Š” Lifecycle ๋กœ ์ง€์ •๋œ๋‹ค. ๋ฒ”์œ„๋กœ ์ง€์ •๋œ Lifecycle ์ด ์™„์ „ํžˆ ๋๋‚ ๋•Œ ๊นŒ์ง€ ๋ฉ”๋ชจ๋ฆฌ์— ๋‚จ์•„์žˆ๋‹ค. ์œ„ ์ฝ”๋“œ์— ์•กํ‹ฐ๋น„ํ‹ฐ์—์„œ ๋ทฐ๋ชจ๋ธ์„ ์ดˆ๊ธฐํ™”ํ•  ๋•Œ ktx ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒฝ์šฐ ๊ฐ์ฒด์˜ ๋ฒ”์œ„๋ฅผ ์‰ฝ๊ฒŒ ์ง€์ •ํ•  ์ˆ˜ ์žˆ๋‹ค.

ํ”„๋ž˜๊ทธ๋จผํŠธ๊ฐ„์˜ ๋ฐ์ดํ„ฐ ๊ณต์œ 

ํ•˜๋‚˜์˜ ์•กํ‹ฐ๋น„ํ‹ฐ์—์„œ ๋‘˜ ์ด์ƒ์˜ ํ”„๋ž˜๊ทธ๋จผํŠธ๋ฅผ ์‚ฌ์šฉํ•  ๋•Œ ๊ฐ๊ฐ์˜ ๋ทฐ๋ชจ๋ธ์„ ์ž‘์„ฑํ•˜๊ฒŒ ๋˜๋ฉด ๋‘˜ ์ด์ƒ์˜ ํ”„๋ž˜๊ทธ๋จผํŠธ์—์„œ์˜ ๊ฒฐํ•ฉ์ด ์‰ฝ๊ฒŒ ์ฒ˜๋ฆฌ๋  ์ˆ˜ ์—†๋Š” ๋ถ€๋ถ„์ด๊ธฐ์— ๊ณต์œ ๋˜๋Š” ๋ทฐ๋ชจ๋ธ์„ ์‚ฌ์šฉํ•ด์•ผ ํ•œ๋‹ค.


class ListFragment : Fragment() {

    // ์ดˆ๊ธฐํ™” ๋ฐฉ๋ฒ• 1 fragment-ktx library
    private val viewModel1: SharedViewModel by activityViewModels()

    // ์ดˆ๊ธฐํ™” ๋ฐฉ๋ฒ• 2
    private val viewModel2: SharedViewModel by lazy {
        ViewModelProvider(requireActivity())[SharedViewModel::class.java]
    }

    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        return super.onCreateView(inflater, container, savedInstanceState)

    }
}

class DetailFragment : Fragment() {

    //  Same as above code...
}

์œ„ ์ฝ”๋“œ์™€ ๊ฐ™์ด ์‚ฌ์šฉํ•˜๋ฉด ์•กํ‹ฐ๋น„ํ‹ฐ์— ์—ฐ๊ฒฐ๋œ ๋ทฐ๋ชจ๋ธ ๊ฐ์ฒด๋ฅผ ๊ณต์šฉ์œผ๋กœ ํ”„๋ž˜๊ทธ๋จผํŠธ์—์„œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค. ๋ฐฉ๋ฒ•1 ์—์„œ์ฒ˜๋Ÿผ activity-ktx ์™€ ๊ฐ™์ด fragment-ktx ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๊ฐ„๋‹จํ•˜๊ฒŒ ์ธ์Šคํ„ด์Šคํ™” ํ•  ์ˆ˜ ์žˆ๊ณ , ๋ฐฉ๋ฒ•2 ๋Š” ๊ธฐ์กด ์•กํ‹ฐ๋น„ํ‹ฐ์—์„œ ๋ทฐ๋ชจ๋ธ์„ ์—ฐ๊ฒฐํ•œ๊ฑฐ ๊ฐ™์ด ์‚ฌ์šฉํ•˜๋ฉด ๋œ๋‹ค. ์—ฌ๊ธฐ์„œ๋Š” ViewModelProvider์— Lifecycle์„ this ๋กœ ์„ค์ •ํ•˜๊ฒŒ๋˜๋ฉด ์ž๊ธฐ ์ž์‹ (ํ”„๋ž˜๊ทธ๋จผํŠธ)์— ๋ผ์ดํ”Œ์‚ฌ์ดํด์„ ๋”ฐ๋ผ๊ฐ€๊ธฐ ๋•Œ๋ฌธ์— ์—ฐ๊ฒฐ๋œ ์•กํ‹ฐ๋น„ํ‹ฐ ๋ผ์ดํ”Œ์‚ฌ์ดํด์„์—ฐ๊ฒฐ์‹œ์ผœ์ค˜์•ผ ํ•œ๋‹ค.

reference

Last updated