クイック解決策Hiltは依存関係を検出したものの、その作成方法についての指示が見当たらない場合にこのエラーをスローします。Hiltを工場に例えると、設計図(ブループリント)がないため、組み立てラインが止まってしまった状態です。以下の優先順位に従って修正してください。
- 自作クラスの場合: クラスに
@Inject constructor() を追加します。- インターフェースの場合: Hiltモジュール内で @Binds を使用し、インターフェースと実装クラスを紐付けます。- 外部ライブラリの場合: Retrofit、Room、OkHttp などのクラスには、Hiltモジュール内で @Provides を使用します。- モジュールの場合: モジュールに @Module と @InstallIn の両方のアノテーションが付いているか確認してください。## なぜこのエラーが発生するのか?Dagger/Hiltはコンパイル時のフレームワークです。アプリの実行中に依存関係を探すリフレクションベースのツールとは異なり、HiltはAPKのビルド中にすべてを検証します。依存関係グラフの「リンク」が1つでも欠けていると、コンパイル全体が失敗します。これにより実行時のクラッシュを防げますが、ビルド時に MissingBinding メッセージが表示されることになります。
シナリオ 1:@Inject アノテーションの付け忘れこれは最も頻繁に起こる原因です。クラスの準備はできていても、Hiltはそのインスタンスを作成してよいかどうかを知りません。カスタムクラスの90%は、単にアノテーションを追加するだけで解決します。
// ❌ Hiltはこのクラスを認識できません
class AnalyticsService {
fun logEvent(name: String) { }
}
// ✅ Hiltはこのインスタンスの作成方法を認識しました
class AnalyticsService @Inject constructor() {
fun logEvent(name: String) { }
}
シナリオ 2:インターフェースの注入インターフェースを直接「構築」することはできません。Hiltに AuthRepository を注入するよう指示する場合、どの具体的な実装を使用するかを伝える必要があります。このマッピングには、抽象クラスと @Binds アノテーションを使用します。Hiltが別のファクトリクラスを生成する必要がないため、@Provides よりもメモリ効率が良い方法です。
interface AuthRepository {
fun login(): Boolean
}
class AuthRepositoryImpl @Inject constructor() : AuthRepository {
override fun login() = true
}
@Module
@InstallIn(SingletonComponent::class)
abstract class RepositoryModule {
@Binds
abstract fun bindAuthRepository(
impl: AuthRepositoryImpl
): AuthRepository
}
シナリオ 3:サードパーティライブラリ(Retrofit と Room)自分で作成していないコードに @Inject を追加することはできません。Retrofitなどを使用する場合、ビルダーをどのように構成するかをHiltに正確に伝える必要があります。このようなケースでは、object モジュール内で @Provides アノテーションを使用します。
@Module
@InstallIn(SingletonComponent::class)
object NetworkModule {
@Provides
fun provideRetrofit(): Retrofit {
return Retrofit.Builder()
.baseUrl("https://api.example.com/v1/")
.addConverterFactory(GsonConverterFactory.create())
.build()
}
}
シナリオ 4:スコープの不一致バインディング自体は存在していても、コンポーネントが間違っている場合があります。例えば、ActivityComponent で定義したバインディングを Service や WorkManager に注入しようとすると、Hiltは失敗します。@InstallIn の値を再確認してください。SingletonComponent はアプリ全体で利用可能ですが、ActivityComponent は Activity 内に限定されます。
トラブルシューティング・チェックリスト- プロジェクトのクリーン: ./gradlew clean を実行してください。リファクタリング後、生成された Dagger のコードが古くなっていることがよくあります。- コンストラクタ引数の確認: クラスが3つの引数を取る場合、Hiltはその3つすべてを提供する方法を知っている必要があります。1つでも欠けていると、クラス全体のバインドに失敗します。- KSP/KAPTの確認: 最近 KSP に切り替えた場合は、build.gradle で kapt "com.google.dagger:hilt-compiler:..." が ksp "com.google.dagger:hilt-compiler:..." に置き換わっているか確認してください。- 限定子(Qualifiers): 2つの異なる String 定数を注入する場合などは、Hiltがそれらを区別できるように @Named やカスタム限定子を使用する必要があります。## 確認方法修正を確認するには、Android Studio の Build 出力ウィンドウを開きます。修正が成功すれば、ログに「BUILD SUCCESSFUL」と表示されます。詳細を確認したい場合は、build/generated/source/kapt フォルダを覗いて、Hiltが自動生成した実際の Java コードを確認することもできます。