https://dagger.dev/hilt/android-entry-point


5.3 Core APIs – Android Entry Points

Gradle 플러그인을 사용하는 것을 가정하고 설명하고 있다. 만약 플러그인을 사용하지 않는다면 Gradle 설정하기 섹션을 참조하자.

지원하는 Android 타입

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된 상태다.

유지되는 Fragment

Fragment의 onCreate() 메서드에서 setRetainInstance(true)를 호출하면 구성 변경이 발생해도 Fragment가 소멸-재생성 되지 않고 인스턴스가 유지된다.

Hilt와 함께 사용하는 Fragment는 (의존성 주입의 책임이 있는) 컴포넌트에 대한 참조를 가지고 있고 해당 컴포넌트는 이전 Activity의 인스턴스에 대한 참조를 가지고 있기 때문에 절대로 Fragment 인스턴스가 유지되서는 안된다. 또한 Fragment에 주입된 스코프 된 바인딩 및 프로바이더는 Hilt와 함께 사용하는 Fragment의 인스턴스가 유지될 경우 메모리 누수가 발생할 수 있다. Hilt와 함께 사용하는 Fragment의 인스턴스가 유지되지 않도록 하기위해, Hilt와 Fragment를 같이 사용하는 경우 Fragment의 인스턴스가 유지되면 구성 변경시 런타임 예외가 발생한다.

Hilt를 사용하는 Activity에 Hilt없이 Fragment만 사용하는 경우에는 Fragment의 인스턴스가 유지될 수 있다. 하지만 해당 Fragment가 Hilt를 사용하는 하위 Fragment를 포함한다면 마찬가지로 구성 변경시 런타임 예외가 발생하게 된다.

Note : 권장하지는 않지만, Hilt를 사용하는 Fragment들은 동일한 Activity의 인스턴스로부터 떨어졌다가 다시 붙을 수 있다. Hilt를 사용하는 Fragment는 onAttach() 메서드를 처음 호출 할 때만 의존성 주입이 수행된다. 유지된 Fragment가 다른 Activity 인스턴스에 다시 붙을 수 있기 때문에 이는 Fragment를 유지하는 것과 동일하지 않다. 다시 한번 강조하지만 이 방법은 권장하지 않으며, 각 사용법에 대해 새로운 Fragment 인스턴스를 만드는 것이 간단하다.

Fragment 바인딩과 View

기본적으로 ApplicationComponent 와 ActivityComponent 바인딩은 View에 주입될 수 있다. Fragment에서 이를 가능하게 하기 위해서는 @WithFragmentBindings 어노테이션을 클래스에 추가해야 한다.

@AndroidEntryPoint
@WithFragmentBindings
class MyView : MyBaseView {
    // ApplicationComponent, ActivityComponent, FragmentComponent,
    // ViewComponent의 바인딩들로부터 의존성 주입을 받을 수 있음
    @Inject lateinit var bar: Bar
    
    constructor(context: Context) : super(context)
    constructor(context: Context, attrs: AttributeSet?) : super(context, attrs)

    init {
        // Do something with bar ...
    }

    override fun onFinishInflate() {
        super.onFinishInflate();

        // Find & assign child views from the inflated hierarchy.
    }
}
  1. 지원하는 다른 안드로이드 클래스와는 다르게 BroadcastReceiver만의 Dagger 컴포넌트를 가지고 있지 않고 대신에 ApplicationComponent로부터 간단히 의존성을 주입 받는다.
카테고리: Dagger2

0개의 댓글

답글 남기기

Avatar placeholder

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