티스토리 뷰

728x90

 

Hilt는 안드로이드 스튜디오에서 편리하게 DI를 사용할 수 있도록 Dagger 기반으로 빌드된 라이브러리이다.

프로젝트의 모든 Android 클래스에 컨테이너를 제공하고, 수명 주기를 자동으로 관리하여 DI를 사용한다.

 

1. build.gradle (kts 기준)

프로젝트 수준

plugins {
    id("com.google.dagger.hilt.android") version "2.48" apply false
}

 

모듈 수준

plugins {
    id("kotlin-kapt")
    id("dagger.hilt.android.plugin")
}

dependencies {
    implementation ("com.google.dagger:hilt-android:2.48")
    kapt ("com.google.dagger:hilt-android-compiler:2.48")
}

kapt {
    generateStubs = true
}

코틀린 1.9.0 버전에 맞는 Hilt 버전은 2.48이다.

사용하는 코틀린 버전에 맞게 라이브러리 버전을 선택한다.

 

 

 

2. 애플리케이션 설정

 

@HiltAndroidApp
class MyApplication : Application() {
    ...
}

 

Hilt로 의존성 주입을 하기 위해서는 가장 먼저 Application 클래스에 @HiltAndroidApp 어노테이션을 추가한다.

Hilt가 Application 수명 주기에 연결되어 이와 관련한 의존성을 제공한다.

Application은 앱의 가장 상위 구성요소이므로 다른 구성요소는 이 Application에서 제공하는 의존성을 사용할 수 있다.

 

 

 

3. 안드로이드 클래스

@AndroidEntryPoint
class MainActivity : AppCompatActivity() {
    
    @Inject lateinit var analytics: AnalyticsAdapter
    ...
}

Hilt가 제공하는 안드로이드 구성요소에 @AndroidEntryPoint을 붙인다.

위 어노테이션을 붙임으로써 클래스의 생명주기에 따라 자동으로 Hilt 요소로 인스턴스화되어 의존성 주입이 처리된다.

 

의존성을 주입받기를 원하는 객체 앞에 @Inject를 붙이면, Hilt가 알아서 의존성 주입을 해준다.

코드로 인스턴스를 따로 생성해서 프로퍼티로 저장해두지 않아도 된다.

 

* @Inject 어노테이션이 붙은 프로퍼티는 private일 수 없고, lateinit var으로 지정해주어야 한다.

 

Hilt가 지원하는 안드로이드 클래스

  • Application (@HiltAndroidApp)
  • ViewModel (@HiltViewModel)
  • Activity
  • Fragment
  • View
  • Service
  • BroadcastReceiver

 

 

 

4. 클래스의 생성자

앞에서 @Inject로 의존성 주입 받기를 원하는 객체를 지정했다.

그러기 위해서는 Hilt가 인스턴스를 생성하기 위한 정보를 알아야 한다.

 

class AnalyticsAdapter @Inject constructor(
    private val service: AnalyticsService
) {
    ...
}

Hilt에게 정보를 제공하기 위해서 생성자 주입을 사용한다.

위 코드와 같이 클래스의 생성자에 @Inject 어노테이션을 사용하여 인스턴스를 생성할 정보를 제공한다.

 

class AnalyticsService @Inject constructor(
    @ApplicationContext context: Context
) {
    ...
}

생성자의 매개변수로 AnalyticsService가 들어오므로 Hilt에게 AnalyticsService의 정보도 알아야 한다.

만약 이 클래스의 생성자로 context가 필요한 경우, @ApplicationContext@ActivityContext를 사용해 context를 제공한다.

@ApplicationContext는 말그대로 앱의 context가 주입되고, 

@ActivityContext는 이 클래스를 주입받기를 원하는 액티비티의 context가 주입된다.

 

 

 

5. Hilt가 인스턴스 생성 정보를 알지 못하는 경우

외부 라이브러리나 인터페이스인 경우, Hilt가 객체를 찾을 수 없어서 일반적인 방법으로 의존성 주입이 불가능하다.

이때 @Module@InstallIn 어노테이션을 지정하여 Hilt에게 의존성 주입 정보를 제공해야 한다.

 

@Module을 통해 특정 유형의 인스턴스를 제공하는 방법을 알려주고,

@InstallIn을 통해 각 모듈을 사용하거나 설치할 클래스를 알려준다.

 

 

 

5-1. 외부 라이브러리 객체 주입

클래스가 외부 라이브러리에서 제공되기 때문에 클래스 파일이 현재 프로젝트에 존재하지 않는 경우, 

Hilt가 인스턴스를 생성할 수 없다. (ex: Retrofit, OkHttpClient, Room의 Database)

@Module
@InstallIn(ActivityComponent::class)
object AnalyticsModule {

  @Provides
  fun provideAnalyticsService(
    ...
  ): AnalyticsService {
      return Retrofit.Builder()
               .baseUrl("https://example.com")
               .build()
               .create(AnalyticsService::class.java)
  }
}

@Module 클래스 내에 @Provides로 지정된 함수를 생성한다.

함수 내부에 인스턴스를 생성하는 코드를 작성하여 Hilt에게 인스턴스를 제공하는 방법을 알려준다.

 

 

5-2. 인터페이스의 구현체 주입

만약 어떤 액티비티에서 AnalyticsService 타입의 인스턴스를 주입받기를 원하는데,

AnalyticsService가 인터페이스라면 Hilt는 인스턴스를 생성할 수 없을 것이다.

interface AnalyticsService {
  fun analyticsMethods()
}

class AnalyticsServiceImpl @Inject constructor(
  ...
) : AnalyticsService {
    ...
}

@Module
@InstallIn(ActivityComponent::class)
abstract class AnalyticsModule {

  @Binds
  abstract fun bindAnalyticsService(
    analyticsServiceImpl: AnalyticsServiceImpl
  ): AnalyticsService
}

대신 @Module로 지정된 abstract 클래스 내에 @Binds로 지정된 abstract 함수를 생성하고,

그 함수의 매개변수로 인터페이스 구현체 클래스가 어떤 것인지 지정해야 한다.

또한 함수의 리턴타입은 인터페이스를 구현한 클래스가 아닌 인터페이스로 지정한다.

이 경우 무조건 클래스와 함수가 abstract여야 한다.

 

여기서 @InstallIn(ActivityComponent::class)인 이유는, 이 인스턴스를 액티비티에 주입해야 하기 때문이다.

 

 

 

6. @InstallIn

@InstallIn 어노테이션의 파라미터로 의존성을 주입받을 대상을 지정할 수 있다.

예시 코드에서는 ActivityComponent::class만 사용했는데, 

아래와 같이 의존성 주입 대상에 따라 여러 파라미터를 사용할 수 있다.

@InstallIn 인자 의존성 주입 대상
SingletonComponent Application
ActivityRetainedComponent N/A
ViewModelComponent ViewModel
ActivityComponent Activity
FragmentComponent Fragment
ViewComponent View
ViewWithFragmentComponent @WithFragmentBingings 지정된 View
ServiceComponent Service

 

728x90
250x250
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
TAG
more
«   2024/10   »
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
글 보관함