😽
Dagger Hilt の Context まわりでハマったこと
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)
}
これでビルドエラーが解消されるはずです。
Discussion