일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
- 스택 자바 코드
- 안드로이드 유닛 테스트 예시
- 안드로이드 레트로핏 사용법
- 안드로이드 유닛테스트란
- 안드로이드 라이선스 종류
- 자바 다형성
- jvm이란
- 클래스
- rxjava cold observable
- 멤버변수
- android retrofit login
- 객체
- ar vr 차이
- 2022 플러터 안드로이드 스튜디오
- jvm 작동 원리
- rxjava disposable
- 서비스 vs 쓰레드
- 큐 자바 코드
- 안드로이드 os 구조
- 안드로이드 레트로핏 crud
- 서비스 쓰레드 차이
- Rxjava Observable
- 플러터 설치 2022
- rxjava hot observable
- 안드로이드 라이선스
- ANR이란
- android ar 개발
- 안드로이드 유닛 테스트
- 2022 플러터 설치
- 스택 큐 차이
- Today
- Total
나만을 위한 블로그
[Android] Hilt에 대한 고찰 본문
글 제목에 '고찰'이라는 단어를 써서 거창하게 보이겠지만 사실 Hilt가 무엇인지, 사용되는 몇몇 어노테이션과 Hilt가 어떤 방식으로 작동하는지에 대해 간단하게 기록할 뿐인 포스팅이다. 원래 "Hilt란? Hilt의 작동방식과 사용되는 어노테이션" 이란 제목으로 쓰려고 했지만 너무 길어서 '고찰'이란 단어로 퉁쳤다.
Hilt란?
먼저 Hilt가 무엇인지부터 알아보자. 다음은 안드로이드 디벨로퍼와 코드랩, Hilt 공식 홈페이지에서 설명하는 Hilt다.
https://developer.android.com/training/dependency-injection/hilt-android?hl=ko
Hilt는 프로젝트에서 수동 종속 항목 삽입을 실행하는 상용구를 줄이는 안드로이드용 종속 항목 삽입 라이브러리다. 수동 종속 항목 삽입을 실행하려면 모든 클래스와 종속 항목을 수동으로 구성하고 컨테이너를 사용해서 종속 항목을 재사용, 관리해야 한다
Hilt는 프로젝트의 모든 안드로이드 클래스에 컨테이너를 제공하고 생명주기를 자동 관리함으로써 앱에서 DI를 사용하는 표준 방법을 제공한다. Hilt는 Dagger가 제공하는 컴파일 시간 정확성, 런타임 성능, 확장성 및 안드로이드 스튜디오 지원의 이점을 누리기 위해 인기 있는 DI 라이브러리 Dagger를 기반으로 빌드되었다...(중략)
https://developer.android.com/codelabs/android-hilt#0
...(중략) DI를 구현하면 다음과 같은 이점이 있다.
- 코드 재사용 가능
- 리팩토링 편의성
- 테스트 편의성
Hilt는 안드로이드용 종속 항목 삽입 라이브러리로 프로젝트에서 수동 DI를 사용하는 상용구 코드를 줄여준다. 종속 항목을 직접 삽입하려면 모든 클래스와 클래스의 종속 항목을 수동 생성하고 컨테이너를 써서 종속 항목을 재사용하고 관리해야 한다. Hilt는 앱에 DI를 삽입하는 표준 방식으로, 프로젝트의 모든 안드로이드 컴포넌트에 컨테이너를 제공하고 컨테이너의 생명주기를 자동 관리한다. 이 방식은 많이 사용되는 DI 라이브러리인 Dagger를 활용한 것이다...(중략)
Hilt는 Dagger DI를 안드로이드 앱에 통합하는 표준 방법을 제공한다. Hilt의 목표는 다음과 같다.
- 안드로이드 앱용 Dagger 관련 인프라 단순화
- 앱 간의 설정, 가독성/이해 및 코드 공유를 용이하게 하기 위한 표준 컴포넌트 및 범위 세트 생성
- 다양한 빌드 유형(테스트, 디버그, 릴리즈)에 서로 다른 바인딩을 프로비저닝하는 쉬운 방법 제공
Hilt는 Dagger 설정 코드를 생성하는 코드로 작동한다. 이것은 Dagger를 쓰는 대부분의 상용구를 없애고 실제로 객체를 생성하는 방법과 객체를 주입할 위치를 정의하는 측면만 남긴다. Hilt는 Dagger 컴포넌트와 코드를 생성해서 안드로이드 클래스(액티비티 및 프래그먼트)를 자동 삽입한다. Hilt는 전이 클래스 경로를 기반으로 표준 Android Dagger 컴포넌트 세트를 생성한다. 이를 위해선 Hilt 어노테이션으로 Dagger 모듈을 표시해서 Hilt에 들어가야 하는 컴포넌트를 알려야 한다...(중략)...Gradle 사용자의 경우 이 클래스를 확장하는 것은 내부에서 바이트코드 변환으로 수행된다. 테스트에서 Hilt는 프로덕션과 마찬가지로 Dagger 컴포넌트를 생성한다...(중략)
이 3가지 글을 읽고 유추할 수 있는 건 크게 아래와 같다고 생각된다.
- Hilt는 Dagger의 단점을 보완해서 만들어진 DI 라이브러리다
- Hilt는 Dagger에 비해 상대적으로 적은 코드로도 DI를 구현할 수 있다
또한 기존에 존재하던 Dagger 라이브러리는 개발자가 만들어야 하는 파일과 사용해야 하는 어노테이션이 많아서 불편하고 귀찮은 구석이 많았다. 거기 사용된 코드를 줄이면서도 DI를 적용할 수 있게 됐으니 안드로이드 개발자 입장에선 좋은 변화였다. 안드로이드 측에서도 이를 알았는지 처음에는 의존성 주입하면 Dagger를 밀어줬는데 현재는 Hilt를 조금 더 밀어주는 걸 볼 수 있다.
그리고 Hilt를 사용하는 개발자는 Dagger 컴포넌트를 직접 정의하거나 인스턴스화하지 않는다. Hilt가 미리 생성되어 정의된 컴포넌트를 제공하기 때문이다.
그 외에 의존성 주입에 관련된 내용은 다른 사람들이 쓴 글이나 예전에 작성한 포스팅을 참고하자.
https://onlyfor-me-blog.tistory.com/373
Hilt 컴포넌트 계층 구조 다이어그램 + a
아래 이미지는 Hilt를 사용해서 앱에 DI를 적용했을 때 만들어질 수 있는 앱 아키텍처다.
아래는 Hilt 공식 홈페이지에서 제공하는 Hilt 컴포넌트 계층 구조 다이어그램이다.
각 컴포넌트 위의 어노테이션은 해당 컴포넌트의 수명에 대한 바인딩 범위 지정에 쓰이는 범위 지정 어노테이션이고, 컴포넌트 밑의 화살표는 모든 하위 컴포넌트를 가리킨다. 자식 컴포넌트의 바인딩은 일반적으로 상위 컴포넌트의 모든 바인딩에 종속될 수 있다.
아래는 애플리케이션 컴포넌트와 주변 클래스 간의 관계를 그림으로 나타낸 것이다.
Hilt 어노테이션
다음은 Hilt에서 사용되는 어노테이션에 대한 설명이다. 모든 어노테이션을 다 써본 건 아니고 사용했던 것만 찾아서 쓴다.
- @Module : 이 어노테이션이 붙은 클래스는 Hilt에게 이 클래스를 생성, 제공해주는 역할을 맡게 된다. 즉 Hilt에게 의존성 주입을 할 모듈(클래스)이 뭔지 알려주는 어노테이션이다. 모듈 클래스명은 XXXModule, 객체를 제공할 메서드명은 provideXXX() 형태로 짓는 관례가 있다
- @InstallIn : 이 어노테이션이 달린 모듈 클래스에서 제공하는 종속 객체의 사용 범위를 특정 안드로이드 컴포넌트에 지정한다. 여러 인스턴스를 만들지 않고 단일 인스턴스를 만들려면 provider 함수에 @Singleton 어노테이션을 달아야 한다. MVVM에 Repository 패턴을 적용할 경우 Repository는 뷰, 뷰모델과 별도로 존재해야 하고 어디서든 접근할 수 있어야 하기 때문에 @InstallIn(SingletonComponent::class) 형태로 써서 싱글턴 모듈임을 나타낸다.
- @Provides : 외부 라이브러리 클래스를 제공하는 경우(종속 객체를 반환하는 메서드를 작성해야 하는 경우)나 빌더 패턴으로 생성되야 하는 클래스의 경우 생성자 주입이 어려울 수 있는데 이 때 사용하는 어노테이션
- @Singleton : 컴포넌트 인스턴스가 존재할 경우 해당 인스턴스가 하나뿐임을 나타내는 어노테이션. ApplicationScope(범위)를 갖는다
- @AndroidEntryPoint : 액티비티, 프래그먼트, 뷰, 서비스, 브로드캐스트 리시버 등의 안드로이드 컴포넌트에서 멤버 인젝션을 활성화할 때 사용된다. 안드로이드 컴포넌트에 이 어노테이션을 달지 않으면 그 안에 필드나 메서드를 주입할 수 없다. 즉 @Inject 어노테이션을 쓸 수 없다
- @HiltAndroidApp : Application을 상속받는 클래스에서 필드, 메서드 주입을 활성화하는 어노테이션이다. @HiltAndroidApp을 사용한 Application을 상속받는 클래스는 매니페스트의 name 속성에 반드시 등록해야 한다. 등록하지 않으면 런타임 에러가 발생한다.
- @HiltViewModel : Hilt가 뷰모델 주입을 할 수 있도록 도와주는 어노테이션이다. AAC ViewModel과 Navigation Graph의 SharedViewModel도 지원한다
- @Inject : 모든 클래스의 생성자, 필드, 메서드 앞에 붙어서 생성자, 필드, 메서드 주입을 가능하게 하는 어노테이션이다. 내 경우 뷰모델의 생성자에 사용해서 UseCase 또는 Repository를 주입받을 때 사용한다
- @Retention : 이 어노테이션이 달린 타입의 어노테이션이 유지되는 기간을 나타낸다. 기본값은 RetentionPolicy.CLASS다
- @Qualifier : javax 주입 패키지에서 제공하는 어노테이션. 종속성 규정(유형은 같지만 인스턴스가 다른 객체를 구별할 때)에 사용한다.
설명이 많이 빈약하니 이해가 잘 안되는 어노테이션들은 꼭 구글링해서 어떤 어노테이션인지 정도는 이해한 다음 사용하자.
@AndroidEntryPoint에 대해선 아래 이미지를 참고하자. @AndroidEntryPoint를 사용한 경우와 사용하지 않은 경우를 비교한 이미지다.
@Retention에 설정할 수 있는 값은 총 3가지인데 자세한 설명은 아래 링크를 참고한다.
https://developer.android.com/reference/java/lang/annotation/RetentionPolicy
참고한 사이트)
https://medium.com/mindorks/qualifiers-in-dagger-android-development-c0574cca87a2
https://sas-study.tistory.com/329
https://dagger.dev/hilt/application
https://proandroiddev.com/all-about-hilt-a-dependency-injection-framework-869b9c2bcb09
https://aroundck.tistory.com/7985
'Android' 카테고리의 다른 글
[Android] CameraX 코드랩 뜯어보기 - 1 - (0) | 2022.06.05 |
---|---|
[Android] Apostrophe not preceded by \ 에러 해결 (0) | 2022.06.03 |
[Android] minSdkVersion이 26 미만일 때 코틀린으로 UTC 시간을 원하는 형식으로 바꾸는 법 (0) | 2022.06.01 |
[Android] Hilt 사용 시 Check that your Kotlin version is >= 1.0: java.lang.IllegalStateException 에러 해결 (0) | 2022.05.29 |
[Android] RxBinding으로 체크박스 체크 상태 관리하기 (0) | 2022.05.23 |