본문 바로가기
ANDROID/Android Jetpack

[Android/Jetpack] AAC - ViewModel

by 주 녕 2021. 7. 27.
728x90

https://developer.android.com/

AAC 중 LifecycleLiveData에 대해 알아보았다. 앞선 포스팅에서도 알 수 있듯이 Android 공식 문서에서 MVVM 아키텍처에 대한 내용을 계속해서 다루고 있다는 것을 알 수 있다. 오늘은 AAC의 ViewModel에 대해 알아보겠다.

 

[Android/Jetpack] AAC - Lifecycles

이 포스팅에 앞서 MVVM 아키텍처와 AAC에 대해 알아보았다. 이제는 AAC의 5가지 라이브러리를 Android developer 문서를 통해 알아볼 예정이다. Lifecycles에 대한 내용이 잘 이해가 되지 않는다면 MVVM이 어

junyoung-developer.tistory.com

 

[Android/Jetpack] AAC - LiveData

LiveData 식별 가능한(Observable) 데이터 홀더 클래스 LiveData는 Activity, Fragment, Service 등 다른 앱 구성요소의 수명 주기를 고려(Lifecycle-aware)한다. 수명 주기 인식을 통해 LiveData는 활성(active)..

junyoung-developer.tistory.com

 

ViewModel

androidx.lifecycle.ViweModel

ViewModel 클래스는 수명 주기를 고려하여 UI 관련 데이터를 저장하고 관리하도록 설계됨

  • ViewModel의 목적 : Activity 또는 Fragment에 필요한 정보를 획득하고 유지하는 것
  • ViewModel은 일반적으로 LiveData 또는 Data Binding을 통해 Activity나 Fragment가 감지할 정보를 노출함

 

❓ MVVM 패턴의 ViewModel과 AAC의 ViewModel

원래 ViewModel은 MVVM 패턴의 구성요소로 존재했다. (ViewModel은 Android 앱 개발에서만 사용되는 개념이 아님)

이전 포스팅에서도 다루었지만 MVVM 패턴은 Model, View, ViewModel로 구성된 소프트웨어 디자인 패턴이다.

여기서 ViewModel의 역할은 View를 표현하기 위한 데이터와 관련된 비즈니스 로직을 갖고 있는 것이다. 

 

Google은 MVVM 패턴의 구성요소로 사용되었던 ViewModel을 Android 앱 개발에 최적화하기 위해 라이브러리화하여 제공한다.

따라서 해당 라이브러리의 ViewModel 클래스를 사용함으로써 Android MVVM 디자인 패턴을 쉽게 구현할 수 있다.

 

🚫 ViewModel을 사용하지 않으면 생길 수 있는 문제점

  1. 시스템에서 UI 컨트롤러를 제거하거나 다시 만드는 경우, 컨트롤러에 저장되어 있던 모든 일시적인 UI 관련 데이터가 삭제된다
    • 데이터가 단순한 경우 onSaveInstanceState() 메서드를 사용하여 onCreate()의 번들에서 데이터를 복원할 수 있음
    • BUT, 이 접근 방법은 직렬화했다가 다시 역직렬화할 수 있는 소량의 데이터에만 적합함 
  2. UI 컨트롤러가 반환하는 데 시간이 걸릴 수 있는 비동기 호출을 자주 해야 한다.
    • 비동기 호출 관리와 호출 제거 시 시스템에서 호출을 정리하는지 확인하는 것에는 많은 유지관리가 필요하고, 구성 변경 시 화면이 다시 생성되는 경우 이미 수행된 호출을 다시 호출하는 리소스 낭비가 발생할 수도 있음
    • *UI 컨트롤러의 역할① UI에 데이터를 표시하거나 ② 사용자의 이벤트에 반응해야 하고  ③ 운영체제와 앱의 커뮤니케이션을 담당하는 것
    • UI 컨트롤러에 DB나 네트워크에서 데이터 로드를 책임지도록 요구하면 클래스가 팽창됨 → UI 컨트롤러에 과도한 책임 할당 → 다른 클래스로 작업이 위임되지 않고, 처리할 작업의 양이 많아짐 && 테스트의 어려움

따라서, UI 컨트롤러 로직에서 View의 데이터 소유권을 분리하는 방법이 훨씬 쉽고 효율적임

 

 

ViewModel의 수명주기

Activity가 회전(rotated)을 거친 다음 끝날 때까지 다양한 수명 주기 상태를 나타낸 그림이다.

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

https://developer.android.com/topic/libraries/architecture/viewmodel?hl=ko

 

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.
    }
}

우선 ViewModel 클래스를 상속하는 서브 클래스를 정의한다.

class MyActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        // 시스템의 activity의 onCreate() 첫번째 호출에 ViewModel을 생성한다.
        // 재생성된 activity들은 첫번째 activity에 의해 생성된 같은 MyViewModel 객체를 받는다.

        // 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
        })
    }
}
    var viewModel = ViewModelProvider(this, ViewModelProvider.NewInstanceFactory()).get(MyViewModel::class.java)

위의 예시는 안드로이드 공식 문서에서 activity-ktx artifact를 사용한 경우이다.

ViewModel 객체에는 LiveData 객체와 같은 LifecycleObservers가 포함될 수 있지만, 수명주기를 인식하는 Observble의 변경사항을 관찰해서는 안된다. 또한 Acitivty Context 참조를 포함하는 클래스를 참조해선 안된다.

 


reference>

 

728x90

댓글