【问题标题】:DAO Injection problem - RoomDatabase not found with Hilt AndroidDAO 注入问题 - 在 Hilt Android 中找不到 RoomDatabase
【发布时间】:2020-08-24 08:43:02
【问题描述】:

所以我正在尝试在个人项目中使用 Room。我已经实现了我的实体、dao 和我的 roomdatabase 扩展应用程序类:

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

    companion object {
        const val DATABASE_NAME = "MyDb"
    }

    abstract fun getUserDao(): UserDao
}

不过,我也在尝试使用 Hilt DI,所以,我创建了一个这样的模块:

@InstallIn(ApplicationComponent::class)
@Module
object PersistenceModule {

    lateinit var database: MyDatabase

    @Provides
    @Singleton
    fun provideDatabase(@ApplicationContext context: Context): MyDatabase{
        database =  Room.databaseBuilder(
            context,
            MyDatabase::class.java,
            MyDatabase.DATABASE_NAME
        )
            .fallbackToDestructiveMigration()
            .build()

        return database
    }

    @Provides
    @Singleton
    fun provideUserDao(db: MyDatabase): UserDao {
        return db.getUserDao()
    }
}

我觉得一切都很好。但是,当我尝试编译时,我收到了以下错误消息:

找不到 androidx.room.RoomDatabase 的类文件

知道我错过了什么吗?

如果它可以帮助你,我试图改变我的 build.gradle :

实现“androidx.room:room-runtime:2.3.0-alpha02”

到这里:

api "androidx.room:room-runtime:2.3.0-alpha02"

这样,它编译成功,但我认为这不是一个好习惯,查看我找到的教程。

如果您需要有关我的代码的更多详细信息,请不要犹豫。

感谢您的回答:)

编辑:

我的房间 build.gradle :

implementation "androidx.room:room-runtime:2.3.0-alpha02"
kapt "androidx.room:room-compiler:2.3.0-alpha02"
implementation "android.arch.persistence.room:runtime:1.1.1"
kapt "android.arch.persistence.room:compiler:1.1.1"

还有这个:

apply plugin: 'kotlin-kapt'

编辑 2:

我想我找到了问题的原因。我在这样的类中调用了我的 DAO 方法:

@Singleton
class DBManagerImpl @Inject constructor(
    private val userDao: UserDao
) : DBManager {

    override fun insertUser(userDBEntity: UserDBEntity) {
       userDao.insertUser(userDBEntity)
    }
}

如果我评论“private val userDao:UserDao”行,似乎问题出在userDao注入原因,我不再有错误了。所以我认为我的问题来自于我注入 dao 对象的方式。

【问题讨论】:

    标签: android kotlin dependency-injection android-room dagger-hilt


    【解决方案1】:

    我遇到了这个问题,因为我正在向核心模块添加空间依赖项,所以对于那些使用模块化架构的人,请确保您也将空间依赖项添加到应用程序模块

    【讨论】:

      【解决方案2】:

      由于您没有提供如何创建 dao 对象,因此我编写了自己的并在此答案中提供。这应该有效:

      数据库类

      @Database(version = 1,entities = [UserDBEntity::class])
      abstract class MyDataBase() : RoomDatabase() {
          
         abstract fun myDao(): UserDao
      
         companion object {
            val DATABASE_NAME = "my_db"
         }
      }
      

      DAO

      @Dao
      inteface UserDao {
         // your functions
         @Query("SELECT * FROM UserDBEntity")
         suspend fun get(): List<User>
      
         @Insert(onConflict = OnConflictStrategy.REPLACE)
         suspend fun insert(entity: UserDBEntity)
      }
      

      房间模块

      @InstallIn(ApplicationComponent::class)
      @Module
      object RoomModule {
         @Singleton
         @Provides
         fun provideMyDB(@ApplicationContext context: Context): MyDataBase {
             return Room.databaseBuilder(context, 
                     MyDataBase::class.java,
                     MyDataBase.DATABASE_NAME
               ).fallbackToDestructiveMigration().build()
         }
      }
      
      @Singleton
      @Provides
      fun provideMyDao(myDB: MyDataBase): UserDao {
          return myDB.myDao()
      }
      

      【讨论】:

        【解决方案3】:

        如果您使用多个模块,请尝试将依赖项也添加到 App 模块:

        build.gradle(应用程序)

        implementation "androidx.room:room-runtime:${versions.androidx_room}"
        implementation "androidx.room:room-ktx:${versions.androidx_room}"
        kapt "androidx.room:room-compiler:${versions.androidx_room}"
        

        【讨论】:

          【解决方案4】:

          我遇到了同样的问题。它可以用 Dagger 修复,但不能用 Hilt 修复。至少现在。似乎目前最好的解决方案是使用api 而不是implementation。如果你强烈想避免它,你可以使用这样的东西:

          @InstallIn(ApplicationComponent::class)
          @Module
          object PersistenceModule {
          
              lateinit var database: MyDatabase
              
              private fun getDatabase(context: Context): MyDatabase {
                      if (!::database.isInitialized) {
                          database = Room.databaseBuilder(
                              context,
                              MyDatabase::class.java,
                              MyDatabase.DATABASE_NAME
                          )
                              .fallbackToDestructiveMigration()
                              .build()
                      }
                      return database
                  
              }
          
              @Provides
              @Singleton
              fun provideUserDao(@ApplicationContext context: Context): UserDao {
                  return getDatabase(context).getUserDao()
              }
          }
          

          但是,正如我所说 - 也许现在最好将 api 留在 gradle 中

          【讨论】:

            【解决方案5】:

            尝试“api“androidx.room:room-runtime:2.3.0-alpha02”而不是“实现”androidx.room:room-runtime:2.3.0-alpha02“”。 我不知道为什么,但它对我有用

            【讨论】:

              【解决方案6】:

              你的 app gradle 文件中有 2 行吗:

              apply plugin: 'kotlin-kapt'
              
              kapt "androidx.room:room-compiler:2.2.5"
              

              【讨论】:

              • 是的,我的 build.gradle 中有这个(在我上面的问题中添加):应用插件:'kotlin-kapt' implementation "androidx.room:room-runtime:2.3.0-alpha02 " kapt "androidx.room:room-compiler:2.3.0-alpha02" 实现 "android.arch.persistence.room:runtime:1.1.1" kapt "android.arch.persistence.room:compiler:1.1.1"
              【解决方案7】:

              好的,所以,看来这是有效的:

              lateinit var database: MyDatabase
              
              @Provides
              @Singleton
              fun provideDatabase(@ApplicationContext context: Context): MyDatabase{
                  database = Room.databaseBuilder(
                      context,
                      MyDatabase::class.java,
                      MyDatabase.DATABASE_NAME
                  )
                      .fallbackToDestructiveMigration()
                      .build()
              
                  return database
              }
              
              
              @Provides
              @Singleton
              fun provideUserDao(): UserDao {
                  return database.getUserDao()
              }
              

              实际上,我必须在我提供的所有 dao 中重用数据库变量。我还不明白为什么,我一直在寻找。

              编辑:

              没关系...它在编译时有效,但在我启动应用程序时无效:

              lateinit 属性数据库尚未初始化

              【讨论】:

                猜你喜欢
                • 1970-01-01
                • 2021-04-13
                • 1970-01-01
                • 2022-01-09
                • 2021-05-08
                • 1970-01-01
                • 2021-02-12
                • 1970-01-01
                • 1970-01-01
                相关资源
                最近更新 更多