首页 > 解决方案 > 如何使用 Android Room 查询预加载的数据库文件?

问题描述

我正在尝试创建一个 Android 应用程序,我在其中单独处理数据库(尝试使用 DB Browser for SQLite)。然后我将 db 文件粘贴到我的项目中并使用 Room 加载数据。但是,我在获取任何结果时遇到了麻烦,因为看起来我的查询没有返回任何结果。

我在 DB Browser 中的表名为“Users”,以“ID”、“FirstName”和“LastName”为列。我将其保存为“testDB.db”。然后,我将此文件放入 Android Studio 中创建的名为“assets”的目录中。

这是我尝试使这个简单的测试代码工作的类:

User class:
@Entity(tableName = "Users")
data class User(
    @PrimaryKey var ID: Int,
    @ColumnInfo (name = "FirstName") val firstName: String,
    @ColumnInfo (name = "LastName") val lastName: String) {
}

UserDao class:
@Dao
interface UserDao {
    @Query("SELECT * FROM Users")
    fun loadAllUsers(): Array<User>
}

UserDatabase class:
@Database(entities = [User::class], version = 2, exportSchema = false)
abstract class UserDatabase : RoomDatabase() {
    abstract fun userDao(): UserDao

    companion object {
        // Singleton prevents multiple instances of database opening at the
        // same time.
        @Volatile
        private var INSTANCE: UserDatabase? = null

        fun getDatabase(context: Context, scope: CoroutineScope): UserDatabase {
            val tempInstance = INSTANCE
            if (tempInstance != null) {
                return tempInstance
            }
            synchronized(this) {
                val instance = Room.databaseBuilder(
                    context.applicationContext,
                    UserDatabase::class.java,
                    "testDB"
                )
                    .createFromAsset("testDB.db") //relative to assets folder
                    .fallbackToDestructiveMigration()
                    .build()
                INSTANCE = instance
                return instance
            }
        }
}

Main Activity:
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.main_activity)

        val job = Job()
        val scope = CoroutineScope(Dispatchers.IO + job)

        var database = UserDatabase.getDatabase(this, scope)

        scope.launch(Dispatchers.IO) {

                val users = database.userDao().loadAllUsers()

                Log.i("test", "First user ${users[0]}") //Crash here since users not picked up


        }

因此,当我尝试使用我的查询并尝试从用户中选择所有内容时,似乎没有选择任何用户,并且当我尝试确定我的结果时应用程序试图崩溃。我试图做的是将我的实体尽可能靠近我的测试数据库文件匹配,但它仍然无法正常工作。

是否有某种方法可以将现有数据库表与您的 @Entity 类相关联,以便您可以选择和显示数据库中的所有数据?

编辑:这是错误

2020-07-27 21:01:13.408 4679-4705/martin.ngyn.dev.testdatabase E/AndroidRuntime: FATAL EXCEPTION: DefaultDispatcher-worker-1
    Process: martin.ngyn.dev.testdatabase, PID: 4679
    java.lang.ArrayIndexOutOfBoundsException: length=0; index=0
        at martin.ngyn.dev.testdatabase.MainActivity$onCreate$1.invokeSuspend(MainActivity.kt:28)
        at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
        at kotlinx.coroutines.DispatchedTask.run(Dispatched.kt:241)
        at kotlinx.coroutines.scheduling.CoroutineScheduler.runSafely(CoroutineScheduler.kt:594)
        at kotlinx.coroutines.scheduling.CoroutineScheduler.access$runSafely(CoroutineScheduler.kt:60)
        at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.run(CoroutineScheduler.kt:740)

所以几乎查询没有返回任何东西。

标签: androiddatabaseandroid-room

解决方案


推荐阅读