Android Compose Hilt
사용 언어: Kotlin 1.9.0
사용 버전: Android Studio Hedgehog 2023.1.1 Patch 1
Hilt는 DI(Dependency Injection, 의존성 주입)를 편하게 하기 위한 라이브러리입니다.
Dagger라는 DI 라이브러리를 Android에 사용하기 편하게 수정한 게 Hilt입니다.
공식 사이트입니다.
사용 버전: Android Studio Hedgehog 2023.1.1 Patch 1
안드로이드 컴포즈 Hilt를 알아보겠습니다.
Hilt는 DI(Dependency Injection, 의존성 주입)를 편하게 하기 위한 라이브러리입니다.
Dagger라는 DI 라이브러리를 Android에 사용하기 편하게 수정한 게 Hilt입니다.
공식 사이트입니다.
참고 프로젝트:
우선, 이러한 dependencies가 필요합니다.
app 용 build.gradle에 현재 필요한 두 개만 적어줍니다.
implementation("com.google.dagger:hilt-android:2.50")
kapt("com.google.dagger:hilt-compiler:2.50")
kapt를 인식하지 못하네요.
Project 용 build.gradle로 갑니다.
kotlin("kapt") version "1.9.0"을 적어줍니다.
그 후, app 용 build.gradle로 와서 kotlin("kapt")를 적어줍니다.
그리고 밑에 kapt를 적고
correctErrorTypes = true를 적어줍니다.
Sync now를 눌러주세요.
간편하게 사용하기 위한 Hilt Gradle Plugin을 추가해 줍시다.
project 용 build.gradle로 갑니다.
id("com.google.dagger.hilt.android") version "2.50" apply false
추가해 줍니다.
app 용 build.gralde로 갑니다.
id("com.google.dagger.hilt.android")
enableAggregatingTask = true
추가해 줍니다.
enableAggregatingTask는 Hilt annotation processors의 컴파일 시간을 줄여주고 호출이 될 때만 실행되게 만들어줍니다.
Sync now를 눌러주세요.
HIlt dependency 추가는 완료됐습니다.
Hilt를 사용하기 위해서는 Custom Application이 필요합니다.
@HiltAndroidApp을 적어줍니다.
AmphibiansApplication.kt
다음으로 필요한 게 AndroidEntryPoint입니다.
Activity
Fragment
View
Service
BoradcastReceiver
위의 Android classes에 Hilt를 적용하려면 @AndroidEntryPoint가 필요합니다.
이 앱은 Activity가 하나뿐이기 때문에 Activity 위에다가 적어줍니다.
MainActivity.kt
수동으로 Dependency Injection이 된 것들을 Hilt로 대체합니다.
AppContainer.kt
amphibiansInfoRepository를 주입하는 곳으로 갑니다.
Factory에서 사용되네요.
AmphibiansViewModel.kt
해당 Factory 코드를 지우고 위로 가서,
@HiltViewModel과 @Inject constructor를 적어줍니다.
amphibiansViewModel을 그냥 viewModel()로 변경해 줍니다.
AmphibiansApp.kt
AmphibiansInfoRepository가 interface이므로 @Provides나 @Binds를 사용해서 Hilt를 사용하게 해줘야 합니다.
아래의 NetworkAmphibiansInfoRepository에 @Singleton, @Inject constructor를 적어줍니다.
AmphibiansInfoRepository.kt
@Singleton은 Scoped라고 하며, 요런 생명 주기를 가집니다. 즉, Singleton은 application 생명주기를 따릅니다.
그래서 같은 application 일 때에는 같은 값만 전달합니다.
Unscopped는 매 요청마다 새로운 instance를 생성해서 전달합니다.
어떤 Component를 사용할지는 어떤 생명주기를 따라야 할지를 생각한 뒤 적용하면 됩니다.
AmphibiansInfoRepository는 인터페이스라서 @Module이 필요합니다.
di package를 만들고 NetworkModule이라는 파일을 만듭니다.
NetworkModule.kt
@Module을 적어줍니다. 이것은 Dagger에서부터 비롯된 거라서 적어줘야 합니다.
@InstallIn은 어떠한 Scope를 사용할지 결정합니다.
그리고 @Binds를 사용하면 abstract를 사용하기 때문에 상위 class도 abstract class가 되었습니다.
impl에 NetworkAmphibiansInfoRepository를 넣고 반환 값으로 우리가 Inject할 interface AmphibiansInfoRepository를 적어줍니다. 그러면 Hillt가 AmphibiansInfoRepository를 찾을 때, NetworkAmphibiansInfoRepository를 활용하여 AmphibiansInfoRepository를 만듭니다.
@Binds와 @Provides는 차이가 있습니다.
@Binds는 parameter가 하나만 들어가고, 함수의 body(내용)이 없습니다.
@Provides는 여러 parameters가 들어가고, 함수의 body가 있습니다. 외부에 있는 코드를 불러올 때 사용합니다.
이러한 차이로 @Binds와 @Provides는 하나의 Module에 넣기가 힘듭니다.
여기도 Inject가 필요합니다.
AmphibiansRemoteDataSource.kt
AmphibiansApi를 위한 Module을 또 만듭니다.
여기서는 @Provides를 사용합니다.
왜냐하면, retrofit은 외부 라이브러리라서 @Binds로 해결할 수 없습니다.
AmphibiansApiModule.kt
amphibiansAPI
ioDispatcher
이 두 파라미터 또한 Inject가 필요합니다.
AmphibiansRemoteDataSource.kt
ioDispatcher를 위한 module이 필요합니다.
CoroutineDispatcherModule.kt
자, 이제 App container를 지웁니다.
그리고 Application에서 appContainer를 모두 지웁니다.
AmphibiansApplication.kt
실행합시다.
잘 작동하네요!
Manual Dependency Injection에서 Hilt Dependency Injection으로 성공적으로 전환하였습니다.
Android Compose Hilt with test와 이어집니다.
끝.
카테고리: Android, Compose
댓글
댓글 쓰기
궁금한 점은 댓글 달아주세요.
Comment if you have any questions.