https://dagger.dev/hilt/quick-start


4. Quick Start

Introduction

Hilt를 사용하면 안드로이드 앱에 의존성 주입을 쉽게 할 수 있다. 이 튜토리얼에서는 기존 앱에 Hilt를 사용하도록 안내한다.

Gradle vs 비-Gradle 사용자

Gradle 사용자의 경우, Hilt Gradle 플러그인은 Hilt 어노테이션의 사용으로 인해 Hilt가 생성하는 클래스에 대한 직접적인 참조를 피함으로써 Hilt를 보다 쉽게 ​사용할 수 있도록 한다.

Gradle 플러그인이 없으면 어노테이션에 기본 클래스를 지정하고 어노테이션이 달린 클래스는 생성된 클래스를 상속해야 한다

@HiltAndroidApp(MultiDexApplication::class)
class MyApplication : Hilt_MyApplication()

Gradle 플러그인을 사용한다면 어노테이션이 달린 클래스는 기본 클래스를 직접적으로 상속할 수 있게 된다.

@HiltAndroidApp
class MyApplication : MultiDexApplication()

앞으로 나오는 예제들은 Hilt Gradle 플러그인을 사용하는 것을 가정한다.

Hilt Application

Hilt를 사용하는 모든 앱은 @HiltAndroidApp이 달린 Application 클래스를 포함해야 한다. @HiltAndroidApp은 Hilt 컴포넌트의 코드 생성과 컴포넌트를 사용하는 Application의 기본 클래스를 생성하게 된다. 코드 생성에는 모든 모듈에 대한 액세스 권한이 필요하므로 Application 클래스를 컴파일하는 대상에는 전이 의존성에 모든 Dagger 모듈이 있어야 한다.

Note : 전이 의존성이란? 어떤 라이브러리를 의존성으로 추가하면 그 라이브러리의 의존성도 함께 의존하게 되는데, 이를 전이 의존성(transitive dependencies)라고 한다.

@AndroidEntryPoint가 달린 다른 안드로이드 프레임워크 클래스와 마찬가지로 Application에도 멤버 주입이 된다. 이는 super.onCreate()가 호출 된 후 Application의 필드에 의존성 주입이 이루어지는 것을 의미 한다.

예를 들어 일반적인 Dagger 사용시 MyApplication이 MyBaseApplication을 상속하는 구조이면서 멤버 변수로 Bar를 가지고 있다고 가정해보자.

class MyApplication : MyBaseApplication() {
    @Inject lateinit var bar: Baroverride fun onCreate() {
        super.onCreate()

        val myComponent =
            DaggerMyComponent.builder()
                ...
                .build()

        myComponent.inject(this)
    }
}

앞에서 살펴본 코드는 Hilt를 사용하면 다음과 같이 멤버 주입이 된다.

@HiltAndroidApp
class MyApplication : MyBaseApplication() {
    @Inject lateinit var bar: Bar
    override fun onCreate() {
        super.onCreate() // super.onCreate()에서 의존성 주입을 하게 된다.
        // 여기에서 bar 변수를 사용할 수 있다.
    }
}

@AndroidEntryPoint

Application에서 멤버 주입이 가능하게 설정하고 나면, 다른 안드로이드 클래스들에서도 @AndroidEntryPoint 어노테이션을 사용하여 멤버 주입을 하는 것이 가능해진다. @AndroidEntryPoint를 사용할 수 있는 타입은 다음과 같다.

  • Activity
  • Fragment
  • View
  • Service
  • BroadcastReceiver

Hilt와 ViewModel의 사용은 직접적으로 지원하지 않는 대신에 Jetpack extension을 통해 지원한다. 다음 예제는 어떻게 Activity에 어노테이션을 추가 할 수 있는지 보여준다. 다른 타입의 경우도 Activity와 동일한 방법으로 진행된다.

Activity에서 멤버 주입을 하기 위해서 @AndroidEntryPoint를 추가 하자.

@AndroidEntryPoint
class MyActivity : MyBaseActivity() {
    @Inject lateinit var bar: Bar // ApplicationComponent 또는 ActivityComponent으로 부터 의존성이 주입된다.
    
    override fun onCreate() {
      // super.onCreate()에서 의존성 주입이 발생한다.
      super.onCreate()

      // Do something with bar ...
    }
}
Note:Hilt는 현재 ComponentActivity를 상속한 Activity만 지원하고 있고 Fragment의 경우 androidx 라이브러리의 Fragment를 상속한 경우에만 지원한다. 현재 안드로이드 플랫폼에 있는 Fragment는 deprecated된 상태다.

Hilt 모듈

Hilt의 모듈은 표준 Dagger 모듈로 @InstallIn이라는 추가적인 어노테이션을 갖는다. @InstallIn은 Hilt의 표준 컴포넌트들 중 어떤 컴포넌트에 모듈을 설치할지 결정한다.

Hilt 컴포넌트가 생성될 때 모듈들은 추가된 @InstallIn과 함께 알맞은 컴포넌트 또는 서브컴포넌트에 설치 된다. Dagger와 같이 컴포넌트에 모듈을 설치하면 해당 모듈에 바인딩된 의존성들은 컴포넌트 내 다른 바인딩 또는 다른 하위 컴포넌트의 바인딩이 접근하는 것을 허용한다. 바인딩 된 의존성에 @AndroidEntryPoint 클래스가 접근 하는 것 또한 가능하다. 해당 컴포넌트의 대한 바인딩 스코프를 지정할 수도 있다.

@InstallIn 사용하기

모듈에서 @InstallIn 어노테이션을 추가하는 것으로 Hilt 컴포넌트에 모듈이 설치 된다. Hilt를 사용할 때 Dagger모듈 상에 이러한 @InstallIn 어노테이션은 필수지만 이 검사는 선택적으로 비활성화 할 수 있다.

Note : 만약 모듈이 @InstallIn 어노테이션을 가지고 있지 않다면 해당 모듈은 컴포넌트에 설치되지 않아 컴파일 에러를 발생 시킨다.

@InstallIn 어노테이션에 어떤 컴포넌트가 모듈이 설치될 적당한 Hilt 컴포넌트인지 명시해야한다. 예를들면 애플리케이션 스코프에서 어떤 바인딩이든 사용할 수 있도록 모듈을 설치하려면 ApplicationComponent를 사용해야 한다.

@Module
@InstallIn(ApplicationComponent.class) // 생성되는 ApplicationComponent에 FooModule을 설치함
public final class FooModule {
    @Provides
    static Bar provideBar() {...}
}
카테고리: Dagger2

0개의 댓글

답글 남기기

Avatar placeholder

이메일은 공개되지 않습니다. 필수 입력창은 * 로 표시되어 있습니다.