| 일 | 월 | 화 | 수 | 목 | 금 | 토 |
|---|---|---|---|---|---|---|
| 1 | 2 | 3 | 4 | 5 | 6 | |
| 7 | 8 | 9 | 10 | 11 | 12 | 13 |
| 14 | 15 | 16 | 17 | 18 | 19 | 20 |
| 21 | 22 | 23 | 24 | 25 | 26 | 27 |
| 28 | 29 | 30 | 31 |
- onRestart()
- fragment
- onStart()
- 풀리퀘스트
- onSaveInstanceState()
- ViewModel
- arcitecture
- onCreate()
- NavGraph
- TransactionTooLargeException
- 열거
- 깃허브
- configuration change
- 프래그먼트
- 가시성
- LiveData
- Navigation component
- IntArray
- LifecycleOwner
- onPause()
- onDestory()
- Backing property
- Navgivation
- pullrequest
- onStop()
- Navigation Graph
- MVVM
- UI controller
- Bundle
- onResume()
- Today
- Total
밑빠진 지식에 블로그 쓰기
ViewModel 본문
아키텍처는 앱에서 클래스 간에 책임을 할당하는데 도움이 되는 가이드라인을 제공합니다.
잘 설계된 앱 아키텍처는 앱을 확장하고 향후 추가 기능으로 확항하는데 도움이 됩니다.
또 팀 협업이 더 쉬워 집니다.
일반적인 아키텍처 원칙은 관심사 분리와 모델에서 UI 구동입니다.
관심사 분리
관심사 분리 디자인 원칙에 따르면 앱은 각각 별도의 책임이 있는 클래스로 나누어야 합니다.
모델에서 UI 구동
또 다른 중요한 원칙은 모델, 바람직하게는 영구 모델에서 UI를 구동해야 한다는 것입니다.
model은 앱의 데이터 처리를 담당하는 구성요소 입니다.
앱의 뷰와 앱 컴포넌트로 부터 도릭적이므로, 모델은 앱의 생명주기 및 관련 문제의 영향을 받지 않습니다.
Android아키텍처의 주요 클래스 또는 구성 요소는 UI컨트롤러(엑티비티/프래그먼트), ViewModel, LiveDate 및 Room입니다.
이런 구성요소는 생명주기의 어떤 복잡성을 처리하고 생명주기와 관련된 문제를 방지하는데 도움이 됩니다.

UI controller(Acitivy / Fragment)
액티비티와 프래그먼트는 UI controller이다. UI 컨트롤러는 화면에 뷰를 그리고, 사용자 이벤트를 캡처하고, 사용자와 상호 작용하는 UI와 관련된 모든 항목을 제어합니다. 앱의 데이터 또는 모든 데이터 처리에 대한 로직은 UI 컨트롤러 클래스(액티비티/프래그먼트) 에 있으면 안됩니다.
Android 시스템(Android OS)는 사용자의 특정 상호작용이나 메모리조건같은 상황에서 UI컨트롤러를 파괴할수 있습니다.이러한 이벤트는 제어할 수 없으므로 앱의 데이터나 상태를 UI컨트롤러(액티비티/프래그먼트)에 저장하면 안됩니다.
그 대신에 데이터에 대한 로직을 ViewModel에 추가해야 합니다.
예를 들어 Unscramble앱에서 단어, 점수, 및 단어의 수가 프래그먼트(UI 컨트롤러)에 표시 됩니다.
뒤섞인 다음 단어를 파악하거나 점수와 단어수 계산과 같은 계산은 ViewModel에 있어야 합니다.
ViewModel
뷰모델을 뷰에 표시되는 앱 데이터의 모델 입니다. 모델을 앱의 데이터 처리를 담당하는 구성요소 입니다. 이것을 통해 앱은 모델에서 UI를 구동하는 아키텍처 원칙을 따를 수 있습니다.
뷰모델은 UI컨트롤러(액티비티,프래그먼트)가 소멸되고 Android 프레임워크(Android system, Android OS)프레임워크에서 다시 생성될 때 소멸되지 않은 앱 관련 데이터를 저장합니다. ViewModel 객체는 구성변경(Configuration change)동안 자동으로 유지됩니다.(UI컨트롤러(액티비티,프래그먼트) 인스턴스처럼 소멸되지 않음). 따라서 보유하고 있는 데이터는 다음 생성되는 액티비티 또는 프래그먼트 인스턴스에서 즉시 사용할 수 있습니다.
앱에서 ViewModel을 구현하려면 아키텍처 구성 요소 라이브러리에서 가져온 ViewModel 클래스를 확장하고 해당 클래스 내에 앱 데이터를 저장합니다.
| Fragment / activity (UI controller) responsibilities | ViewModel responsibilities |
| 액티비티와 프래그먼트는 뷰와 데이터를 화면에 그리고 사용자 이벤트에 응답하는 역할을 합니다. | ViewModel은 UI에 필요한 모든 데이터를 보유하고 처리하는 역할을 합니다. 뷰 계층 구조(예: 뷰 바인딩 개체)에 액세스하거나 액티비티 또는 프래그먼트에 대한 참조를 보유해서는 안 됩니다. |
ViewModel에 데이터 저장하기 | Android Developers
이 Codelab에서는 아키텍처 구성요소 중 하나인 ViewModel을 사용하는 방법을 알아봅니다. 구성 변경 중에 앱 데이터를 유지하도록 ViewModel을 구현합니다.
developer.android.com
Kotlin property delegate Kotlin 속성 대리자
Kotlin의 속성 위임은 getter-setter 책임을 다른 클래스에 전달하는 데 도움이 됩니다.
이 클래스(대리자 클래스라고 함)는 속성의 getter 및 setter 함수를 제공하고 해당 변경 사항을 처리합니다.
대리자 속성은 by 절과 대리자 클래스 인스턴스를 사용하여 정의됩니다.
// Syntax for property delegation
var <property-name> : <property-type> by <delegate-class>()
앱에서 아래와 같이 기본 GameViewModel 생성자를 사용하여 보기 모델을 초기화하는 경우:
private val viewModel = GameViewModel()
그런 다음 기기가 구성 변경을 거치면 앱은 viewModel 참조의 상태를 잃게 됩니다.
예를 들어 기기를 회전하면 활동이 소멸되고 다시 생성되며 다시 초기 상태의 새로운 뷰 모델 인스턴스를 갖게 됩니다.
대신 속성 위임 방식을 사용하고 viewModel 개체의 책임을 viewModels라는 별도의 클래스에 위임합니다. 즉, viewModel 개체에 액세스할 때 내부적으로 위임 클래스인 viewModels에 의해 처리됩니다. 대리자 클래스는 첫 번째 액세스에서 viewModel 개체를 생성하고 구성 변경을 통해 해당 값을 유지하고 요청 시 값을 반환합니다.
가시성 변경자로 캡슐화를 해야하는 이유
이 문제를 해결하려면 속성의 가시성 수정자를 공개로 만들 수 없습니다. 다른 클래스에서 데이터를 편집할 수 없어야 합니다.이는 외부 클래스가 뷰 모델에 지정된 게임 규칙을 따르지 않는 예기치 않은 방식으로 데이터를 변경할 수 있기 때문에 위험합니다. 예를 들어 외부 클래스가 점수를 음수 값으로 변경할 수 있습니다.
뷰모델의 생명주기
프레임워크는 액티비티 또는 프래그먼트의 범위가 살아있는 한 ViewModel을 활성 상태로 유지합니다.
화면 회전과 같은 구성 변경으로 인해 소유자가 소멸되는 경우 ViewModel은 소멸되지 않습니다. 소유자의 새 인스턴스는 다음 다이어그램과 같이 기존 ViewModel 인스턴스

에 다시 연결됩니다.