LoginSignup
6
1

More than 3 years have passed since last update.

Dagger Hilt の Context まわりでハマったこと

Posted at

Dagger Hilt では、Context クラスが必要な場合のために、@ApplicationContextアノテーションと@ActivityContextアノテーションが用意されています。
Hilt を使用した依存関係の注入  |  Android デベロッパー  |  Android Developers
Context を使う上でハマったポイントがあったので、備忘録として残しておきます。

事例

例えば SharedPreferences をラップした、SharedPreferencesWrapperクラスをMainActivityで使う場合を考えてみます。

MainActivity.kt
@AndroidEntryPoint
class MainActivity : AppCompatActivity() {

    @Inject
    lateinit var sharedPreferencesWrapper: SharedPreferencesWrapper
    ...
}
SharedPreferencesWrapper.kt
/**
 * SharedPreferencesのラッパークラス
 */
class SharedPreferencesWrapper @Inject constructor(@ActivityContext context: Context) {

    private val sharedPreferences = context.getSharedPreferences("test", Context.MODE_PRIVATE)
    ...
}

そして、SharedPreferencesWrapper のインスタンスを提供するため、ActivityProvidesModuleクラスを以下の通り作成します。

ActivityProvidesModule.kt
/**
 * DI用ProvidesModule
 * @Inject が付いたプロパティや引数に提供する値の実体を定義
 */
@Module
@InstallIn(ActivityComponent::class)
object ActivityProvidesModule {

    /**
     * SharedPreferencesWrapperの提供
     */
    @Provides
    fun provideSharedPreferencesWrapper(context: Context): SharedPreferencesWrapper {
        return SharedPreferencesWrapper(context)
    }
}

ここでアプリをビルドすると、以下のエラーが出力されます。

/Users/Hitoshi/src/MyApplication/app/build/generated/source/kapt/debug/com/kmdhtsh/myapplication/MainApplication_HiltComponents.java:144: エラー: [Dagger/MissingBinding] android.content.Context cannot be provided without an @Provides-annotated method.
  public abstract static class ApplicationC implements MainApplication_GeneratedInjector,
                         ^
      android.content.Context is injected at
          com.kmdhtsh.myapplication.ActivityProvidesModule.provideSharedPreferencesWrapper(context)
      com.kmdhtsh.myapplication.SharedPreferencesWrapper is injected at
          com.kmdhtsh.myapplication.MainActivity.sharedPreferencesWrapper
      com.kmdhtsh.myapplication.MainActivity is injected at
          com.kmdhtsh.myapplication.MainActivity_GeneratedInjector.injectMainActivity(com.kmdhtsh.myapplication.MainActivity) [com.kmdhtsh.myapplication.MainApplication_HiltComponents.ApplicationC → com.kmdhtsh.myapplication.MainApplication_HiltComponents.ActivityRetainedC → com.kmdhtsh.myapplication.MainApplication_HiltComponents.ActivityC]

エラーを直訳すると、「Context は@Providesアノテーションメソッドがないと提供できません」と出ています。
解決策として、ActivityProvidesModuleクラスのprovideSharedPreferencesWrapperメソッドにも、同様のアノテーションを付与します。

ActivityProvidesModule.kt
/**
 * SharedPreferencesWrapperの提供
 */
@Provides
fun provideSharedPreferencesWrapper(@ActivityContext context: Context): SharedPreferencesWrapper {
    return SharedPreferencesWrapper(context)
}

これでビルドエラーが解消されるはずです。

6
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
1