4

所以我正在尝试在个人项目中使用 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 对象的方式。

4

7 回答 7

3

我遇到了这个问题,因为我在核心模块中添加了房间的依赖关系,所以对于那些使用模块化架构的人来说,确保你也向应用程序模块添加了房间的依赖关系

于 2021-03-17T15:10:07.010 回答
1

我有同样的问题。它可以用 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()
    }
}

但是,正如我所说 - 也许现在最好离开apigradle

于 2021-02-09T14:50:22.310 回答
1

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

于 2021-05-02T06:35:57.990 回答
1

如果您使用多个模块,请尝试向 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}"
于 2020-09-30T07:45:50.727 回答
1

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

数据库类

@Database(version = 1,entities = [UserDBEntity::class])
abstract class MyDataBase() : RoomDatabase() {
    
   abstract fun myDao(): UserDao

   companion object {
      val DATABASE_NAME = "my_db"
   }
}

@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()
}
于 2020-09-05T20:06:18.120 回答
0

app gradle 文件中有 2 行:

apply plugin: 'kotlin-kapt'

kapt "androidx.room:room-compiler:2.2.5"
于 2020-08-24T13:49:53.567 回答
0

好的,所以,这似乎有效:

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 属性数据库尚未初始化

于 2020-08-26T09:54:39.993 回答