https://goni95.tistory.com/173
2017년 Google I/O에서 발표한 Android Architecture Components(AAC)는 안드로이드 개발자들에게 테스트와 유지보수가 편리한 어플리케이션을 만드는 것을 목적으로 출시된 라이브러리 모음입니다.
2018년 Google I/O에서 발표한 차세대 Android API인 Android Jetpack이 출시되면서 AAC가 Jetpack의 섹션 중 하나로 포함되었습니다.
1️⃣ AAC ViewModel
MVVM의 VM인 ViewModel과 자주 언급되는데 MVVM에서의 ViewModel과 AAC ViewModel은 다릅니다. 단순히 이름만 같다고 생각하면 됩니다.
1. AAC ViewModel은 무엇일까요?
시스템에서 UI가 제거되거나 새로 생성되는 경우! 즉, 액티비티나 프래그먼트와 같은 UI 컨트롤러가 제거되거나 새로 생성되는 경우 생명주기에 의해 UI 컨트롤러가 가지던 데이터가 모두 날아가게 됩니다.
Todo List를 저장하기 위해서 입력해둔 정보들이 화면 전환으로 인해서 View가 다시 그려지면서 데이터가 날라가는 상황을 예로 들 수 있는데 해당 문제를 해결하고자 UI 컨트롤러에서 DB에 직접 연결하고 데이터를 저장 및 가져오는 작업을 하게되면 복잡성이 높아지고 테스트를 어렵게 만드는 원인이 되기 때문에 Android의 수명 주기를 고려하여 UI 컨트롤러에서 데이터 소유에 대한 로직을 분리하고 데이터를 효율적으로 관리하도록 하기위해서 탄생한 것이 AAC ViewModel 입니다.
2. AAC ViewModel 생성
AAC ViewModel을 생성하기 위해선 ViewModelProvider 객체가 필요하며 ViewModelProvider를 생성하기 위해선 ViewModelStoreOwner와 ViewModelProvider.Factory가 필요합니다.
ViewModelProvider 객체를 통해 ViewModel 인스턴스를 요청하면 ViewModelProvider 내부에서 ViewModelStoreOwner를 참조하여 ViewModelStore를 가져와 ViewModelStore에 이미 생성된(저장된) ViewModel 인스턴스가 존재하면 ViewModelStore에 저장된 ViewModel 인스턴스를 사용하고 없다면 ViewModelFactory를 통해 새로운 ViewModel을 생성하게 됩니다.
ComponentActivity와 Fragment는 ViewModelStoreOwner 인터페이스를 구현하고 있으므로, ComponentActivity의 서브클래스인 AppCompatActivity를 사용하거나 Fragment를 사용할 경우 별도로 ViewModelStoreOwner를 구현할 필요없이 ViewModelProvider 생성자의 첫번째 인자로 자신을 넘겨주면 됩니다.
ViewModelProvider.Factory의 경우 생성자가 없는 ViewModel을 인스턴스화 한다면 ViewModelProvider 내에 선언된 NewInstanceFactory 클래스를 사용하고 그 외엔 직접 ViewModelProvider.Factory를 구현해야 합니다.
3. AAC ViewModel를 어떻게 활용하는 것이 좋을까요?
앞서 말했듯이 AAC ViewModel은 Android의 수명 주기를 고려하여 UI 관련 데이터를 저장하고 관리하도록 설계되어 있기 때문에 ViewModel이 알아서 Activity가 완전히 종료되거나 Fragment가 분리될 때 까지 메모리에 남아있습니다.
TIP : AAC ViewModel은 구성 변경(configuration change)에서도 살아남습니다.(화면 회전, 언어 변경 등)
개발자는 View의 LifeCycle에 따라 Android 시스템이 호출하는 콜백함수를 이용해 UI 컨트롤러를 관리하고 AAC ViewModel에선 UI 컨트롤러가 필요로 하는 데이터를 관리하고 UI 컨트롤러가 데이터를 참조하도록 작성하는 것이 좋습니다.
4. 주의할 점
위 이미지를 보면 VIewModel이 UI 컨트롤러와 별도의 생명주기를 가지며 Activity 보다 더 긴 수명주기를 가지는 것을 알 수 있습니다.
즉, ViewModel에서 Activity에 대한 Context를 참조하거나 Context 인스턴스 또는 언제든 파괴될 수 있는 객체를 포함하는 경우 Garbage Collector에 의해 처리되어야 할 액티비티 또는 프래그먼트를 계속 참조하고 있어 대상에서 제외되고 그 만큼 메모리 누수가 발생하거나 Crash가 발생할 수 있습니다.
이러한 이유로 ViewModel에서 Context를 포함할 수 있도록 ApplicationContext를 제공하는 AndroidViewModel을 사용하면 되지만 ViewModel을 사용하는 것을 권장한다고 합니다.
또한 ViewModel에서 getString(R.string.xxx) 통해 문자열을 관리할 경우 시스템 언어를 변경해도 이전 언어의 문자열이 남아있기 때문에 View와 Binding 할 때 리소스의 아이디를 참조하도록 하여 올바른 언어 문자열이 반영되도록 해야합니다.
2️⃣ MVVM ViewModel
두 ViewModel의 차이점을 알아보기 위해 MVVM의 ViewModel이 무엇인지 알아봅시다.
1. MVVM *아키텍처 패턴은 무엇일까요?
MVVM은 비즈니스 로직과 프레젠테이션 로직을 UI로 부터 분리해 테스트, 유지 보수, 재사용이 용이하고 Model, View, ViewModel로 구성됩니다.
*아키텍처 패턴 : 소프트웨어 구조에서 발생하는 문제점들의 해결책으로 구성요소 간의 관게를 구조화하여 설계한 시스템의 전반적인 구조를 의미합니다.
2. MVVM 구성 요소
Model은 어플리케이션의 데이터를 캡슐화하는 비시각적 클래스로 도메인 모델로 생각할 수 있습니다.
View는 사용자에게 보여질 화면을 담당을 의미합니다.
데이터의 변화를 감지하기 위한 옵저버를 가지며 기본적으로 비즈니스 로직을 포함해선 안되지만 UI와 관련된 일부 로직은 가질 수 있습니다.
Android에서는 UI 컨트롤러를 담당하는 Activity, Fragment가 View의 역할을 합니다.
ViewModel은 공용 속성과 공용 명령을 노출하는 View에 대한 추상화로 ViewModel과 View는 일대다 관계를 가질 수 있고 View에게 상태 변화를 알립니다.
View에 필요로 하는 데이터에 대한 비즈니스 로직을 담당해 데이터를 처리하고 제공하는 요소로 View와 Model의 사이에서 매개체의 역할을 합니다.
3. 주의할 점
ViewModel에서 View를 참조하면 ViewModel이 특정 View에 종속되게 되면서 ViewModel을 다른 View에서 재사용할 수 없으며 ViewModel은 View에 표현할 데이터 및 비즈니스 로직을 가져야 하므로 안드로이드 프레임워크에 대한 코드를 가져선 안됩니다. 이를 어길 시 단위 테스트가 불가능 합니다.
3️⃣ AAC ViewModel과 MVVM ViewModel에 대하여
AAC ViewModel과 MVVM의 ViewModel이 무엇인지 알아봤습니다.
결과적으로 MVVM의 ViewModel은 View에 필요한 데이터를 관리하며 비즈니스 로직을 담당하는 요소이고 AAC ViewModel은 Android 수명 주기를 고려하여 UI 관련 데이터를 관리하는 요소라는 것을 파악하고 프로젝트에서 AAC ViewModel을 사용한다고 MVVM 아키텍처 패턴의 ViewModel을 사용한 것이 아니며 AAC ViewModel을 통해 MVVM 패턴의 ViewModel로 구현하기 위해 제약사항 및 주의할 점을 지켜야 한다는 것을 이해하는 것이 이번 글의 목표입니다.
마지막으로 비즈니스 로직과 프레젠테이션 로직을 분리해 ViewModel이 View에 대한 의존성을 갖지않고 View가 ViewModel의 데이터를 관찰하고 업데이트 하기위해서 Databinding과 LiveData를 통한 옵저버 패턴을 적용하는 것이 필수적으로 사용됩니다.
'Android > Android의 모든 것' 카테고리의 다른 글
👋Android의 모든 것 : 1️⃣DialogFragment (0) | 2022.05.11 |
---|---|
👋Android의 모든 것 : 1️⃣MVVM을 위한 Databinding, LiveData 개념과 예제 (0) | 2022.04.26 |
👋Android의 모든 것 : 1️⃣Room, 2️⃣예제(Koin, Room) (0) | 2022.03.28 |
👋Android의 모든 것 : 1️⃣Lottie에 대해서 (0) | 2022.03.25 |
👋Android의 모든 것 : 1️⃣SharedPreference, 2️⃣DataStore (0) | 2022.03.21 |