Android Kotlin应用程序在创建数据库后崩溃,仅在第一次运行时无法写入数据库文件(已锁定)

Android Kotlin应用程序在创建数据库后崩溃,仅在第一次运行时无法写入数据库文件(已锁定),android,sqlite,kotlin,Android,Sqlite,Kotlin,在第一次运行创建SQLite数据库的应用程序时,该应用程序会崩溃,并出现与无法使用SQLite数据库文件(已锁定)相关的错误。这只会在第一次运行时发生,并且应用程序会在每一次运行时成功运行 我认为,当数据库类被实例化并且数据库是第一次被创建时,应用程序试图在创建后不久(或者在创建之前和/或创建期间)使用它,这导致了崩溃 数据库是在我创建的“DatabaseHelper”类的onCreate部分创建的。正在应用程序的主活动中实例化DatabaseHelper 我能告诉应用程序暂停一秒钟左右,以便在

在第一次运行创建SQLite数据库的应用程序时,该应用程序会崩溃,并出现与无法使用SQLite数据库文件(已锁定)相关的错误。这只会在第一次运行时发生,并且应用程序会在每一次运行时成功运行

我认为,当数据库类被实例化并且数据库是第一次被创建时,应用程序试图在创建后不久(或者在创建之前和/或创建期间)使用它,这导致了崩溃

数据库是在我创建的“DatabaseHelper”类的onCreate部分创建的。正在应用程序的主活动中实例化DatabaseHelper

我能告诉应用程序暂停一秒钟左右,以便在第一次运行时创建数据库吗

谢谢

代码片段:

DatabaseHelper和数据库创建:


class DatabaseHelper(context: Context, factory: SQLiteDatabase.CursorFactory?) :
    SQLiteOpenHelper(context, DATABASE_NAME, factory, DATABASE_VERSION),
    PurchasesUpdatedListener, BillingClientStateListener, AcknowledgePurchaseResponseListener {

    companion object {
        private val DATABASE_NAME = "acwa8fz4wo93o28v4"
        private val DATABASE_VERSION = 10
  }

   override fun onCreate(db: SQLiteDatabase) {
        Log.i("MSG", "trying to create DB")

        val CREATE_MY_TABLE = (

                "create table products (" +
                        "productName text, " +
                        "productId text, " +
                        "productDesc text, " +
                        "productLongDesc text, " +
                        "updateFlag bool)"

                )

        db.execSQL(CREATE_MY_TABLE)

        Log.i("MSG", "Created DB")

}

MainActivity中DatabaseHelper的实例化:

class MainActivity : AppCompatActivity() {


    val dbHelper = DatabaseHelper(this, null)  <-- I believe this is where the DB gets created for the first time if not exist..

    //more stuff in Activity below...
附加堆栈跟踪与崩溃

    --------- beginning of crash
2021-04-21 16:34:10.594 17236-17270/com.kaboserv.statestatute E/AndroidRuntime: FATAL EXCEPTION: verify
    Process: com.domain.app, PID: 17236
    android.database.sqlite.SQLiteDatabaseLockedException: database is locked (code 5 SQLITE_BUSY)
        at android.database.sqlite.SQLiteConnection.nativeExecuteForLong(Native Method)
        at android.database.sqlite.SQLiteConnection.executeForLong(SQLiteConnection.java:750)
        at android.database.sqlite.SQLiteSession.executeForLong(SQLiteSession.java:654)
        at android.database.sqlite.SQLiteStatement.simpleQueryForLong(SQLiteStatement.java:109)
        at android.database.DatabaseUtils.longForQuery(DatabaseUtils.java:1017)
        at android.database.DatabaseUtils.longForQuery(DatabaseUtils.java:1005)
        at android.database.sqlite.SQLiteDatabase.getVersion(SQLiteDatabase.java:1093)
        at android.database.sqlite.SQLiteOpenHelper.getDatabaseLocked(SQLiteOpenHelper.java:389)
        at android.database.sqlite.SQLiteOpenHelper.getReadableDatabase(SQLiteOpenHelper.java:340)
        at com.domain.app.dao.DatabaseHelper.verify(DatabaseHelper.kt:197)
        at com.domain.app.ListActivity.verify(ListActivity.kt:529)
        at com.domain.app.ListActivity.access$verify(ListActivity.kt:36)
        at com.domain.app.ListActivity$onCreate$$inlined$schedule$1.run(Timer.kt:149)
        at java.util.TimerThread.mainLoop(Timer.java:562)
        at java.util.TimerThread.run(Timer.java:512)

我知道问题出在哪里了

我所做的是:

在第一次运行时,创建数据库并使用临时存储在数组中的所有项填充它

同时,我有一个函数(verify),运行该函数可以检查数组中的所有项是否都进入了数据库(主要是检测需要添加的条目的添加)。这个verify func遍历数组中的每个项,并检查它是否存在于数据库中,如果不存在,则创建它

它失败了,因为它与第一次运行时的初始输入内容冲突。。崩溃发生在它试图添加一个当时已经存在的项目时


我通过检查运行次数并在第一次运行后进行“验证”来修复此问题。

您似乎错过了在问题中包含错误及其引用的代码的实际操作。错误表示找不到数据库文件。在它说它是由我的日志消息创建之后。明天我将更新帖子以包含完整的消息…当您实例化助手时,数据库文件不会被创建。它是在第一次调用时创建的,例如
getWritableDatabase()
getReadableDatabase()
好的,这是一个很好的线索,因此您建议我在第一次调用此函数时使用计时器?stacktrace看起来不像崩溃,缺少致命异常,更像是捕获并记录的异常。无论如何在该跟踪中,
DatabaseHelper.verify()
是第一个要检查的部分,因为它是代码移动到框架代码的地方。
    --------- beginning of crash
2021-04-21 16:34:10.594 17236-17270/com.kaboserv.statestatute E/AndroidRuntime: FATAL EXCEPTION: verify
    Process: com.domain.app, PID: 17236
    android.database.sqlite.SQLiteDatabaseLockedException: database is locked (code 5 SQLITE_BUSY)
        at android.database.sqlite.SQLiteConnection.nativeExecuteForLong(Native Method)
        at android.database.sqlite.SQLiteConnection.executeForLong(SQLiteConnection.java:750)
        at android.database.sqlite.SQLiteSession.executeForLong(SQLiteSession.java:654)
        at android.database.sqlite.SQLiteStatement.simpleQueryForLong(SQLiteStatement.java:109)
        at android.database.DatabaseUtils.longForQuery(DatabaseUtils.java:1017)
        at android.database.DatabaseUtils.longForQuery(DatabaseUtils.java:1005)
        at android.database.sqlite.SQLiteDatabase.getVersion(SQLiteDatabase.java:1093)
        at android.database.sqlite.SQLiteOpenHelper.getDatabaseLocked(SQLiteOpenHelper.java:389)
        at android.database.sqlite.SQLiteOpenHelper.getReadableDatabase(SQLiteOpenHelper.java:340)
        at com.domain.app.dao.DatabaseHelper.verify(DatabaseHelper.kt:197)
        at com.domain.app.ListActivity.verify(ListActivity.kt:529)
        at com.domain.app.ListActivity.access$verify(ListActivity.kt:36)
        at com.domain.app.ListActivity$onCreate$$inlined$schedule$1.run(Timer.kt:149)
        at java.util.TimerThread.mainLoop(Timer.java:562)
        at java.util.TimerThread.run(Timer.java:512)