首页 > 解决方案 > 如何修复“错误:[Dagger/MissingBinding] androidx.room.RoomDatabase.Callback 不能在没有@Provides-annotated 方法的情况下提供”

问题描述

应用模块.kt

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

@Provides
@Singleton
fun provideTaskDatabase(
    app: Application,
    callback: RoomDatabase.Callback
) = Room.databaseBuilder(app,TaskDatabase::class.java,"task_db")
    .fallbackToDestructiveMigration()
    .addCallback(callback)
    .build()

@Provides
@Singleton
fun provideTaskDao(appDatabase: TaskDatabase): TaskDao {
    return appDatabase.getDao()
}

@ApplicationScope
@Provides
@Singleton
fun provideApplicationScope() = CoroutineScope(SupervisorJob())

@Retention(AnnotationRetention.RUNTIME)
@Qualifier
annotation class ApplicationScope
}

任务视图模型.kt

@HiltViewModel
class TaskViewModel @Inject constructor(
private val taskDao: TaskDao
): ViewModel() {

val searchQuery = MutableStateFlow("")
val sortOrder = MutableStateFlow(SortOrder.BY_DATE)
val hideComplited = MutableStateFlow(false)
@ExperimentalCoroutinesApi
private val taskFlow = combine(
    searchQuery,
    sortOrder,
    hideComplited){
    query,sortorder,hidecomplited ->
    Triple(query,sortorder,hidecomplited)
}
    .flatMapLatest {(query,sortorder,hidecomplicated) ->
    taskDao.getTasks(query,sortorder,hidecomplicated)
}
@ExperimentalCoroutinesApi
val tasks = taskFlow.asLiveData()
}

enum class SortOrder{ BY_DATE,BY_NAME}

回调类

@Database(entities = [Task::class],version = 1)
abstract class TaskDatabase: RoomDatabase() {

abstract fun getDao(): TaskDao

class CallBack @Inject constructor(
    private val database: Provider<TaskDatabase>,
    @AppModule.ApplicationScope private val applicationScope: CoroutineScope
): RoomDatabase.Callback(){
    override fun onCreate(db: SupportSQLiteDatabase) {
        super.onCreate(db)

        val dao = database.get().getDao()

        applicationScope.launch {
            dao.insert(Task("Go to shopping"))
            dao.insert(Task("Go to job"))
            dao.insert(Task("playing football",important = true))
            dao.insert(Task("Programming",checked = true))
            dao.insert(Task("buy something"))
        }
    }
}
}

build C:\Users\User\AndroidStudioProjects\ToDoList\app\build\generated\source\kapt\debug\com\example\todolist\TodoApplication_HiltComponents.java:127: error: [Dagger/MissingBinding] androidx.room.RoomDatabase.Callback cannot be provided without an @Provides-annotated method. public abstract static class SingletonC implements TodoApplication_GeneratedInjector, ^ androidx.room.RoomDatabase.Callback is injected at com.example.todolist.di.AppModule.provideTaskDatabase(�, callback) com.example.todolist.room.TaskDatabase is injected at com.example.todolist.di.AppModule.provideTaskDao(appDatabase) com.example.todolist.room.TaskDao is injected at com.example.todolist.ui.task.TaskViewModel(taskDao) com.example.todolist.ui.task.TaskViewModel is injected at com.example.todolist.ui.task.TaskViewModel_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.example.todolist.TodoApplication_HiltComponents.SingletonC ? com.example.todolist.TodoApplication_HiltComponents.ActivityRetainedC ? com.example.todolist.TodoApplication_HiltComponents.ViewModelC]warning: The following options were not recognized by any

标签: androidkotlinviewmodel

解决方案


对于你使用 callback: RoomDatabase.Callback 作为 fun provideTaskDatabase 中的参数,你需要告诉 dagger 如何创建这样的对象。

@Provides
fun provideCallback() = object : RoomDatabase.Callback() {
 //override and implement methods
}

推荐阅读