You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Dagger Hilt编译报错:AppDatabase无@Provides方法,求排查问题

问题描述

编译错误日志

C:\Users\hasif\AndroidStudioProjects\SamplePhone\app\build\generated\hilt\component_sources\debug\com\sherhotel\samplephone\MyApplication_HiltComponents.java:127: error: [Dagger/MissingBinding] com.sherhotel.samplephone.mhilt.AppDatabase cannot be provided without an @Provides-annotated method.
      public abstract static class SingletonC implements MyApplication_GeneratedInjector,
                             ^
          com.sherhotel.samplephone.mhilt.AppDatabase is injected at
              com.sherhotel.samplephone.mhilt.MyModule.provideDocumentDao(db)
          com.sherhotel.samplephone.mhilt.DocumentDao is injected at
              com.sherhotel.samplephone.mhilt.Repository(dao)
          com.sherhotel.samplephone.mhilt.Repository is injected at
              com.sherhotel.samplephone.mhilt.MyViewModel(db)
          com.sherhotel.samplephone.mhilt.MyViewModel is injected at
              com.sherhotel.samplephone.mhilt.MyViewModel_HiltModules.BindsModule.binds(vm)
          @dagger.hilt.android.internal.lifecycle.HiltViewModelMap java.util.Map<java.lang.String,javax.inject.Provider<androidx.lifecycle.ViewModel>> is requested at
              dagger.hilt.android.internal.lifecycle.HiltViewModelFactory.ViewModelFactoriesEntryPoint.getHiltViewModelMap() [com.sherhotel.samplephone.MyApplication_HiltComponents.SingletonC ? com.sherhotel.samplephone.MyApplication_HiltComponents.ActivityRetainedC ? com.sherhotel.samplephone.MyApplication_HiltComponents.ViewModelC]

Gradle依赖配置

// Dagger-Hilt
    implementation "com.google.dagger:hilt-android:2.43.2"
    kapt "com.google.dagger:hilt-compiler:2.43.2"
    implementation 'androidx.hilt:hilt-navigation-compose:1.0.0'
    kapt 'androidx.hilt:hilt-compiler:1.0.0'
    // Room
    kapt "androidx.room:room-compiler:$room_version"
    implementation "androidx.room:room-runtime:$room_version"
    implementation "androidx.room:room-ktx:$room_version"
    // ViewModel Compose
    implementation "androidx.lifecycle:lifecycle-viewmodel-compose:2.5.1"

相关代码片段

MyModule.kt

@Module
@InstallIn(SingletonComponent::class)
object MyModule {

    @Provides
    @Singleton
    fun provideDatabase(@ApplicationContext appContext: Context): RoomDatabase {
        return Room.databaseBuilder(
            appContext,
            AppDatabase::class.java,
            "wise_pdf_db"
        ).fallbackToDestructiveMigration()
            .build()
    }

    @Provides
    @Singleton
    fun provideDocumentDao(db: AppDatabase): DocumentDao =
        db.documentDao()

}

AppDatabase.kt

@Database(entities = [Document::class], version = 2, exportSchema = false)
public abstract class AppDatabase : RoomDatabase() {

    abstract fun documentDao(): DocumentDao
}

DocumentDao.kt

@Dao
interface DocumentDao {

    @Query("SELECT * FROM my_pdf_docs ORDER BY lastRead DESC")
    fun getRecentDocs(): LiveData<List<Document>>

    @Insert(onConflict = OnConflictStrategy.IGNORE)
    suspend fun insert(document: Document)

    @Query("DELETE FROM my_pdf_docs WHERE id = :id")
    suspend fun delete(id: Int)
}

Document.kt

@Entity(tableName = "my_pdf_docs", indices = [Index(value = ["filePath"], unique = true)])
data class Document(
    @PrimaryKey(autoGenerate = true) val id: Int,
    @ColumnInfo(name = "filePath") val filePath: String,
    @ColumnInfo(name = "lastRead") val lastRead: Long
)

MyViewModel.kt

@HiltViewModel
class MyViewModel @Inject constructor(private val db: Repository) : ViewModel() {
    suspend fun insert(document: Document) {
        db.insert(document)
    }
    val recentDocuments: LiveData<List<Document>> = db.getRecentDocs()
}

Repository.kt

class Repository @Inject constructor(private val dao: DocumentDao) {
    suspend fun insert(document: Document) {
        dao.insert(document)
    }

    fun getRecentDocs(): LiveData<List<Document>> {
        return dao.getRecentDocs()
    }
}

MyApplication.kt

@HiltAndroidApp
class MyApplication : Application()

MainActivity.kt

@AndroidEntryPoint
class MainActivity : ComponentActivity() {
    val viewModel: MyViewModel by viewModels()
}
问题原因与解决方案

核心问题

MyModule中的provideDatabase方法返回类型声明为RoomDatabase,但实际返回的是AppDatabase(RoomDatabase的子类)。Dagger Hilt依赖注入基于静态类型匹配,当provideDocumentDao需要AppDatabase实例时,Hilt找不到对应的@Provides方法——因为你只提供了RoomDatabase类型的实例,而非AppDatabase。

修复步骤

修改provideDatabase方法的返回类型为AppDatabase,让Hilt明确识别你提供的实例类型:

@Provides
@Singleton
fun provideDatabase(@ApplicationContext appContext: Context): AppDatabase {
    return Room.databaseBuilder(
        appContext,
        AppDatabase::class.java,
        "wise_pdf_db"
    ).fallbackToDestructiveMigration()
        .build()
}

验证修复

执行Clean Project -> Rebuild Project,编译错误即可解决。Hilt现在能正确匹配AppDatabase的依赖提供,后续的DocumentDao、Repository、ViewModel依赖链也能正常注入。

内容的提问来源于stack exchange,提问作者lava

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.03 20:31:03