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 둜 μ„€μ •ν•˜κ²Œλ˜λ©΄ 자기 μžμ‹ (ν”„λž˜κ·Έλ¨ΌνŠΈ)에 λΌμ΄ν”Œμ‚¬μ΄ν΄μ„ 따라가기 λ•Œλ¬Έμ— μ—°κ²°λœ μ•‘ν‹°λΉ„ν‹° λΌμ΄ν”Œμ‚¬μ΄ν΄μ„μ—°κ²°μ‹œμΌœμ€˜μ•Ό ν•œλ‹€.

Last updated