티스토리 뷰
안드로이드 공식 문서에 있는 ViewModel의 간단한 예제이다
그도그럴것이 MyViewModel의 생성자에 아무런 인자가 없다
그러니깐 별도의 의존성을 고민할 필요 없이
ViewModelPrivoder를 통해 ViewModel을 생성해서 쓰면 된다
하지만 실제로는 생성자에 아무런 파라메터도 던져지지 않는 형태의 viewmodel을 쓰는 경우가 거의 없다
viewmodel이 UI에 표시할 데이터를 보여주기 위해 필요로 하는
여러 인스턴스들을 넘겨줘야한다(repository나 usecase 같은 것들)
그래서 안드로이드는 Factory라는 클래스를 통해서
viewmodel에 원하는 인자를 넣어 생성할수 있도록 하는 방법을 제공해준다
ViewModelProvider.Factory 를 구현 했다
위의 예제에서는 간단하게 string을 인자로 받는 MainViewModel을 생성했다
이 예제 처럼 create 메소드가 새 인스턴스를 리턴할때
무언가를 넣어서 인스턴스를 초기화할수 있다
즉 우리가 android viewmodel을 사용할때 가장 중요한것은
ViewModelFactory 클래스를 만들어서 해당 팩토리클래스가 적절한 viewmodel 클래스를 반환하도록 하는것에 있다
위의 예제처럼 ViewModelFactory를 구현해서 ViewModel을 생성할때 파라메터들을 직접 주입할수 있게 되었지만
아직 비효율적인 부분들이 남아있다
작은 앱에서는 이런 식의 구현이 나쁘지 않지만
우리가 만약 50개가 넘는, 100개가 넘는 viewmodel을 갖게 된다면
ViewModelFactory가 100개가 넘는 viewmodel의 생성자에 전달해줄 파라메터들까지 잔뜩 안고 있는
거대한 클래스가 되어버린다
바로 이때도 dagger가 이러한 의존성을 주입하는 역할을 할수있다
ViewModelFactory를 dagger를 이용해서 주입하는 방법을 사용해보자
먼저 ViewModelFactory를 만들어보자
ViewModelFactory 클래스의 생성자 파라메터인
Map 객체가 있는데 이게 뜬금없이 어디서 나온거지 당황스러울것이다
바로 이 Map 객체를 이후에 나올 코드의 @IntoMap 어노테이션이 자동으로 생성하게 된다
그러니깐 우리는 그냥 이 factory를 보고 간단히 factory 생성시에 전달될 map 객체는
dagger가 알아서 주입하는구나라고만 생각하면된다
ViewModelFactoryModule은 @Binds를 사용했다
우리가 만든 클래스는 ViewModelFactory인데 필요한 타입은 추상화 되어있는 ViewModelProvider.Factory 클래스이라서
@Provides로 구현해도 되지만 @Binds 를 이용해서 간단하게 구현했다
여기서 중요한 포인트는
@JvmSuppressWildcards 어노테이션의 사용인데 나도 이걸 왜 필요로 하는건지 제대로 이해하지 못했다
다만 이 어노테이션이 없으면 빌드시에 에러가 나니깐 꼭 넣어야한다
자 이제 나머지 클래스의 구현을 살펴보자
MainViewModel과 SplashViewModel이라는 ViewModel을 예제를 위해 만들었다
예제에서는 아무런 생성자 파라메터가 없지만
생성자에서 필요한 repository라던지 usecase를 의존성 주입을 통해 넣으면 된다
ViewModelModule의
@IntoMap 어노테이션은 dagger로 하여금 이 리턴 타입을 map의 value에 넣으라고 알려준다
그럼 이제 map에 value는 들어갔으니 키로 사용될값이 필요한데
바로 @MapKey라는 어노테이션이 그 역할을 한다
ViewModelKey라는 어노테이션을 만들었다 그리고 여기에 @MapKey 어노테이션을 붙였다
우리 생성한 ViewModelKey 라는 어노테이션이 이후에 Key 로 사용할 값을 알려주는 역할을 한다
이후에 사용은
@ViewModelKey(MainViewModel::class)
이런식으로 사용하게 되는데 괄호안에있는 값이 map의 key로 사용되어진다
이렇게 구현함으로서 dagger가 코드를 자동생성해내고
Map객체를 만들어주는데 key로는 Class 타입을, Value로는 ViewModel을 갖게된다
그렇기에 우리는 ViewModelFactory에서 map[modelClass]?.get() 이런식으로 원하는 ViewModel을 가져올수 있는것이다
ViewModelModule에서 공급하는 ViewModel은 추상화된 ViewModel 타입이 필요하므로
물론 @Binds 어노테이션을 사용해서 이렇게 구현해도 된다
자 이제 컴포넌트에서 ViewModelModule과 ViewModelFactoryModule을 연결하면 끝
이렇게 액티비티까지 완성하여 우리가 원하는 dagger + android view model의 조합을 완성했다
코드스니펫만으로는 설명에 한계가 있어서
보다 실무에 가까운 샘플코드를 만들었다
android viewmodel과 dagger를 조합한 완전한 예제를 github에 올려두었다
https://github.com/spotlight21c/DaggerViewModel
조금이나마 도움이 되길
'WEB2.0 > 프로그래밍' 카테고리의 다른 글
구형 리눅스(centos5)에서 아파치 2.4 설치하기 (0) | 2020.04.06 |
---|---|
gitlab 사용시 401 Unauthorized while accessing 오류 발생하면 (0) | 2020.04.05 |
golang 기본 문법 (0) | 2019.12.19 |
Android Architecture Components ViewModel이 왔어요 (0) | 2019.12.18 |
dagger에 context를 주입하는 좋은 방법 @BindsInstance (0) | 2019.12.17 |
- Total
- Today
- Yesterday
- Apple
- 창업
- 아이디어
- 아이폰
- 모바일
- php
- 트위터
- 게임
- 공모전
- 안드로이드
- 자바스크립트
- iPhone
- 경진대회
- 스마트폰
- AWS
- 애플
- android
- 앱스토어
- 웹표준
- 구글
- 어플리케이션
- JavaScript
- 앱
- CSS
- 대학생
- 소프트웨어
- 벤처
- 네이버
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |