개요

ViewModel 클래스는 수명 주기를 고려하여 UI 관련 데이터를 저장하고 관리하도로고 설계되었다. 

Android Framework는 Activity나 Fragment 같은 UI Controller의 수명 주기를 관리한다. Framework는 특정 사용자 작업이나 완전히 통제할 수 없는 기기 이벤트에 대한 응답으로 UI 컨트롤러를 제거하거나 다시 만들도록 결정할 수 있다.

 

시스템에서 UI Controller를 제거하거나 다시 만드는 경우, Controller에 저장된 모든 일시적인 UI 관련 Data는 삭제된다.

 

물론, 데이터가 단순한 경우 Acitivity는 onSaveInstanceState() 메소드를 사용하여 onCreate()의 번들에서 데이터를 복원할 수 있다.

-> 하지만 에로사항들이 있는데,

1. 이 접근 방법은 사용자 목록이나 비트맵과 같은 대용량일 가능성이 높은 데이터가 아닌, 직렬화 했다가 다시 역직렬화할 수 있는 소량의 데이터에만 적합하다.

2. UI Controller가 반환하는 데 시간이 걸릴 수 있는 비동기 호출을 자주 해야 한다는 점이다. UI Controller는 비동기 호출을 관리해야 하며, 메모리 누수 가능성을 방지하기 위해 호출이 제거된 후 시스템에서 호출을 정리하는지 확인해야 한다.

*관리에는 많은 유지관리 필요, 구성 변경 시 개체가 다시 생성되는 경우 개체가 이미 수행된 호출을 다시 호출해야 할 수 있으므로 리소스가 낭비된다.

 

ViewModel 구현

아키텍처 구성요소는 UI의 데이터 준비를 담당하는 UI Controller에 ViewModel 클래스를 제공한다. 

ViewModel 객체는 구성이 변경되는 동안 자동으로 보관되므로, 이러한 객체가 보유한 데이터는 다음 Activity, Fragment에서 즉시 사용할 수 있다.

Ex) 앱에서 사용자 목록을 표시해야 한다면 다음 코드 대로 사용자 목록을 확보하여 Activity나 Fragment 대신 ViewModel에 보관하도록 책임을 할당한다.

class MyViewModel : ViewModel() {
    private val users: MutableLiveData<List<User>> by lazy {
        MutableLiveData<List<User>>().also {
            loadUsers()
        }
    }

    fun getUsers(): LiveData<List<User>> {
        return users
    }

    private fun loadUsers() {
        // Do an asynchronous operation to fetch users.
    }
}

이후 다음과 같이 Activity에서 목록에 엑세스 할 수 있다.

class MyActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        // Create a ViewModel the first time the system calls an activity's onCreate() method.
        // Re-created activities receive the same MyViewModel instance created by the first activity.

        // Use the 'by viewModels()' Kotlin property delegate
        // from the activity-ktx artifact
        val model: MyViewModel by viewModels()
        model.getUsers().observe(this, Observer<List<User>>{ users ->
            // update UI
        })
    }
}

Activity가 다시 생성되면 첫 번째 Activity에서 생성된 동일한 MyViewModel 인스턴스를 받는다. Activity가 완료되면 프레임워크는 리소스를 정리할 수 있도록 ViewModel 객체의 onCleared() 메소드를 호출한다.

 

ViewModel 객체는 뷰 또는 LifecycleOwners의 특정 인스턴스화보다 오래 지속되도록 설계되었다. 이러한 설계로 인해 뷰 및 Lifecycle 객체에 관해 알지 못할 때도 ViewModel을 다루는 테스트를 더 쉽게 작성할 수 있다. ViewModel 객체에는 LiveData 객체와 같은 LifecycleObservers가 포함될 수 있다. 그러나 ViewModel 객체는 LiveData 객체와 같이 수명 주기를 인식하는 Observable의 변경사항을 관찰해서는 안된다.

 

ViewModel의 수명 주기

ViewModel 객체의 범위는 ViewModel을 가져올 때 ViewModelProvider에 전달되는 Lifecycle로 지정된다.

ViewModel은 범위가 지정된 Lifecycle이 영구적으로 경과될 때까지, 즉 Activity에서 Activity가 끝날 때까지 그리고 프래그먼트에서 프래그먼트가 분리될 때까지 메모리에 남아 있다.

일반적으로 시스템에서 Activity 객체의 onCreate() 메소드를 처음 호출할 때 ViewModel을 요청한다. 시스템은 Activity 기간 내내 onCreate() 메소드를 여러 번 호출할 수 있다. ViewModel이 처음 요청되었을 때부터 활동이 끝나고 폐기될 때까지 ViewModel은 존재한다.

 

 

+ Recent posts