→ Android에서 DI를 위한 라이브러리이다. Android의 Activity, Fragment 등 주요 component 들에서 사용할 의존성 객체를 관리해준다. Android 용으로 만들어서 선배 DI 라이브러리인 Dagger보다 훨씬 쓰기 쉽다.
→ 의존성 주입(Dependency Injection)! 특정 a 클래스의 객체가 필요할 때 사용처에서 직접 생성하는 것 보다 전달 받는것이 테스트에도 용이하고 보일러 플레이트 코드를 줄일 수 있고 객체 생성에 필요한 조건이 변경됐을 때 편하게 대응이 가능하다.
Hilt가 Dagger를 기반으로 만들어졌고, 더 편하고, 요즘(2022.07.28 기준) Android 씬에서 DI가 아주 핫한 디자인 패턴이며 hilt가 Android DI에 필수적인 라이브러리이다.
대충 이정도만 짚고 넘어가자.
시작!
일단 dependency 추가 먼저 해주자
// gradle(project)
buildscript {
dependencies {
classpath 'com.google.dagger:hilt-android-gradle-plugin:2.42'
}
}
// gradle(app)
plugins {
id 'dagger.hilt.android.plugin'
id 'kotlin-kapt'
}
dependencies {
implementation "com.google.dagger:hilt-android:2.42"
kapt "com.google.dagger:hilt-android-compiler:2.42"
}
@HiltAndroidApp
class MyApplication : MultiDexApplication() {...}
@HiltAndroidApp 어노테이션이 모든 작업의 시작점이다. Hilt를 사용하는 모든 앱은 이 어노테이션을 추가한 Application class를 정의해야 한다. @HiltAndroidApp이 Application의 생명주기를 참고하여 컴파일 타임 때 필요한 클래스들을 초기화 해주고 의존성 객체를 제공한다.
시작이 반이니 벌써 절반 했다.
이제 의존성을 주입 받아 보쟈. Hilt는 Application, Activity, Fragment, Service, View, BroadcastReceiver, ViewModel 컴포넌트들에 의존성 주입을 도와준다.
Application Class와 마찬가지로 클래스 상단에 어노테이션을 추가해주자.
@AndroidEntryPoint
class MainActivity : AppCompatActivity() {...}
프래그먼트에 지정하면 프래그먼트가 띄워진 액티비티에도 달아주어야 한다.
의존성 주입 방식에 2가지 경우가 있다.
참고: https://f2janyway.github.io/android/hilt/
-> 내가 구현한 클래스
-> 인터페이스 or abstract class 구현체(@Module 사용)
-> 내가 구현할 수 없는 클래스(3rd party library)(@Module 사용)
class DateFormatter @Inject constructor() {
...
}
class의 constructor에 @Inject 붙여준다, 초간단
인스턴스 주입을 위한 모듈을 만들어보자!
@Module
@InstallIn(SingletonComponent::class)
object NetworkModule {
@Singleton
@Provides
fun provideOkHttpClient(): OkHttpClient {...}
어쩌고 저쩌고 구글링 해보면 죄다 Dagger의 개념과 함께 설명하느라 말을 너무 어렵게 한다.(내 기준 ㅎ)
Dagger를 알면 좋겠지만 나중에 하는것으로 하고… 쉽게쉽게 알아보자
@Module은 컴포넌트에 의존성을 제공하는 역할을 한다. 모듈 클래스 내에 선언되는 메서드에 @Provides 를 붙여 컴파일 타임에 의존성을 제공하는 프로바이더를 생성한다. (긍까 간단히 Hilt에게 해당 의존성을 주입하는 방법을 알려준다.)
더 간단히!! @Module은 의존성을 제공하는 클래스에 붙이고, @Provides는 의존성을 제공하는 메소드에 붙인다!
@Provides 는 외부 라이브러리 처럼 클래스를 직접 소유하지 않아서 인스턴스 생성 방법을 모르는 경우 지정해준다.
@Binds → Abstract인 경우 사용
@Installin은 간단히 해당 모듈을 Hilt 표준 컴포넌트들 중 어떤 컴포넌트에 설치할 것인지 결정한다.
간단히!! 해당 모듈에 접근할 수 있는 범위를 지정한다! 컴포넌트들은 밑에 정리.

Dagger에서는 컴포넌트를 직접 정의했어야 하나 보다. Hilt는 제공해주는 위의 컴포넌트들을 편하게 쓰면 된다~
모듈의 Installin에서 지정한 컴포넌트의 스코프와 모듈 내에서 제공되는 인스턴스들의 scope는 동일해야한다. (ex @Installin(ActivitiyComponent.class) 로 설정했으면 해당 모듈의 메소드들의 scope도 다 @ActivityScoped 로 지정해줘야 함.)
따로 scope를 지정하지 않으면 주입이 일어날 때 마다 인스턴스를 생성하고, GC에 의해 삭제됨.
scope를 달아주면 해당 scope에 맞게 create, destroy됨.

이제 의존성 주입을 받자!
@AndroidEntryPoint
class ChangePasswordFragment : Fragment() {
private lateinit var binding: FragmentChangePasswordBinding
@Inject
lateinit var userRepository: UserRepository
@AndroidEntryPoint 를 붙인 곳에서 @Inject 를 통해 의존성 주입 받는다, 초간단
Dagger에서는 기존에 ViewModelProvider를 이용해 직접 뷰모델 inject를 위해 multi 어쩌고 저쩌고를 활용해 직접 구현해줬어야 했는데 이 과정을 @HiltViewModel 이 자동으로 자~알 어디다가 만들어주고 뷰모델 사용처에서 viewModels 확장 함수를 통해 간단히 뷰모델의 의존성을 주입 받을 수 있다.
더 자세한 디테일들은 알아서 찾아보시길……….
Hilt에 대해 더 자세히 이해하기 위해서는 Dagger를 이해하는것이 필요하겠지만 (공부하기 시렁)
일단은 이정도만 이해해도 Hilt를 사용하는데에는 지장 없을 듯 싶다.
Component와 Scope를 정할 때 신경을 쓰는것이 중요하다고 생각된다.
끝!
간단하게 잘 정리하셨네요! 나중에는 적용기도 보여주세요!!