Android上使用Room递归调用getDatabase时出错
我正在尝试使用Room运行查询。但是,当我尝试运行查询时,我得到以下错误Android上使用Room递归调用getDatabase时出错,android,sqlite,android-studio,kotlin,android-room,Android,Sqlite,Android Studio,Kotlin,Android Room,我正在尝试使用Room运行查询。但是,当我尝试运行查询时,我得到以下错误 java.lang.IllegalStateException: getDatabase called recursively at android.database.sqlite.SQLiteOpenHelper.getDatabaseLocked(SQLiteOpenHelper.java:357) at android.database.sqlite.SQLiteOpenHelper.
java.lang.IllegalStateException: getDatabase called recursively
at android.database.sqlite.SQLiteOpenHelper.getDatabaseLocked(SQLiteOpenHelper.java:357)
at android.database.sqlite.SQLiteOpenHelper.getWritableDatabase(SQLiteOpenHelper.java:317)
at androidx.sqlite.db.framework.FrameworkSQLiteOpenHelper$OpenHelper.getWritableSupportDatabase(FrameworkSQLiteOpenHelper.java:92)
at androidx.sqlite.db.framework.FrameworkSQLiteOpenHelper.getWritableDatabase(FrameworkSQLiteOpenHelper.java:53)
at androidx.room.RoomDatabase.inTransaction(RoomDatabase.java:476)
at androidx.room.CoroutinesRoom$Companion.execute(CoroutinesRoom.kt:45)
at androidx.room.CoroutinesRoom.execute(Unknown Source:2)
at com.uwi.loanhub.models.UserDao_Impl.addNewUser(UserDao_Impl.java:132)
at com.uwi.loanhub.models.LoanHubDatabase$UserDatabaseCallback.populateDatabase(LoanHubDatabase.kt:71)
at com.uwi.loanhub.models.LoanHubDatabase$UserDatabaseCallback$onOpen$$inlined$let$lambda$1.invokeSuspend(LoanHubDatabase.kt:55)
at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
at kotlinx.coroutines.DispatchedContinuationKt.resumeCancellableWith(DispatchedContinuation.kt:330)
at kotlinx.coroutines.intrinsics.CancellableKt.startCoroutineCancellable(Cancellable.kt:26)
at kotlinx.coroutines.CoroutineStart.invoke(CoroutineStart.kt:109)
at kotlinx.coroutines.AbstractCoroutine.start(AbstractCoroutine.kt:158)
at kotlinx.coroutines.BuildersKt__Builders_commonKt.launch(Builders.common.kt:56)
at kotlinx.coroutines.BuildersKt.launch(Unknown Source:1)
at kotlinx.coroutines.BuildersKt__Builders_commonKt.launch$default(Builders.common.kt:49)
at kotlinx.coroutines.BuildersKt.launch$default(Unknown Source:1)
at com.uwi.loanhub.models.LoanHubDatabase$UserDatabaseCallback.onOpen(LoanHubDatabase.kt:54)
at com.uwi.loanhub.models.LoanHubDatabase_Impl$1.onOpen(LoanHubDatabase_Impl.java:63)
at androidx.room.RoomOpenHelper.onOpen(RoomOpenHelper.java:136)
at androidx.sqlite.db.framework.FrameworkSQLiteOpenHelper$OpenHelper.onOpen(FrameworkSQLiteOpenHelper.java:142)
at android.database.sqlite.SQLiteOpenHelper.getDatabaseLocked(SQLiteOpenHelper.java:428)
at android.database.sqlite.SQLiteOpenHelper.getWritableDatabase(SQLiteOpenHelper.java:317)
at androidx.sqlite.db.framework.FrameworkSQLiteOpenHelper$OpenHelper.getWritableSupportDatabase(FrameworkSQLiteOpenHelper.java:92)
at androidx.sqlite.db.framework.FrameworkSQLiteOpenHelper.getWritableDatabase(FrameworkSQLiteOpenHelper.java:53)
at androidx.room.RoomDatabase.inTransaction(RoomDatabase.java:476)
at androidx.room.RoomDatabase.assertNotSuspendingTransaction(RoomDatabase.java:281)
at com.uwi.loanhub.models.UserDao_Impl.getUsernamePassword(UserDao_Impl.java:207)
at com.uwi.loanhub.models.UserRepository.getUsernamePassword(UserRepository.kt:15)
at com.uwi.loanhub.models.UserViewModel.getUsernamePassword(UserViewModel.kt:31)
at com.uwi.loanhub.LoginActivityNew$onCreate$2.onClick(LoginActivityNew.kt:54)
at android.view.View.performClick(View.java:7125)
at com.google.android.material.button.MaterialButton.performClick(MaterialButton.java:992)
at android.view.View.performClickInternal(View.java:7102)
at android.view.View.access$3400(View.java:801)
at android.view.View$PerformClick.run(View.java:27301)
at android.os.Handler.handleCallback(Handler.java:883)
at android.os.Handler.dispatchMessage(Handler.java:100)
at android.os.Looper.loop(Looper.java:214)
at android.app.ActivityThread.main(ActivityThread.java:7319)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:492)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:934)
调用此函数时会出现错误:
var userHolderList:List<User> = userViewModel.getUsernamePassword(editText_username_Login_Activity.text.toString(), functions.encryptSys(editText_password_Login_Activity.text.toString()))
在
RoomDatabase.Callback中,您不能使用房间,因为房间还没有准备好。您可以使用提供的SupportSQLiteDatabase
执行所需的操作。感谢您的回复。但是,我不完全理解您的意思,问题在于。@NicoleFoster在您的UserDatabaseCallback
中,您试图使用RoomDatabase
(实例
)及其DAO(数据库.UserDao()
)。这是不受支持的。您的onOpen()
函数将被传递一个SupportSQLiteDatabase
,您可以使用它。好的,当我这样做时,我得到:无法访问主线程上的数据库,因为它可能会长时间锁定UI。
@nicoleforter:YourCoroutineScope
的默认调度程序显然是Dispatchers.main
。使用scope.launch(Dispatchers.IO)
或其他工具来安排在后台线程上执行工作。是的,我尝试使用(Dispatchers.IO)
,但它给出了相同的错误。有没有更简单的方法来做这类事情。问题是当我插入时,它工作得很好。但做一个简单的查询,我得到了这个问题。
@Database(entities = arrayOf(User::class), version = 1, exportSchema = false)
abstract class LoanHubDatabase : RoomDatabase() {
abstract fun UserDao(): UserDao
companion object {
@Volatile
private var INSTANCE: LoanHubDatabase? = null
fun getDatabase(context: Context, scope: CoroutineScope): LoanHubDatabase {
val tempInstance = INSTANCE
if (tempInstance != null) {
return tempInstance
}
synchronized(this) {
val instance = Room.databaseBuilder(
context.applicationContext,
LoanHubDatabase::class.java,
"LoanHub_Database"
).addCallback(UserDatabaseCallback(scope)).build()
INSTANCE = instance
return instance
}
}
}
private class UserDatabaseCallback(private val scope: CoroutineScope) :
RoomDatabase.Callback() {
@RequiresApi(Build.VERSION_CODES.O)
override fun onOpen(db: SupportSQLiteDatabase) {
super.onOpen(db)
INSTANCE?.let { database ->
scope.launch {
populateDatabase(database.UserDao())
}
}
}
@RequiresApi(Build.VERSION_CODES.O)
suspend fun populateDatabase(userDao: UserDao) {
}
}
}