You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Kotlin+SQLite创建表后插入初始数据报错,无法捕获错误码

问题分析与解决

你遇到的运行时错误和无法捕获错误码的问题,核心原因有两个:

1. 手动关闭SQLiteOpenHelper维护的数据库连接

第一个代码片段中,initPoint方法里的wd.close()是致命错误:

  • SQLiteOpenHelper会全权负责数据库连接的生命周期,onCreate方法传入的SQLiteDatabase实例是框架内部复用的连接,绝对不能手动关闭。
  • 一旦提前关闭该连接,后续框架尝试复用连接时会直接抛出IllegalStateException,且这个错误发生在onCreate的try-catch块之外,导致你捕获不到错误信息。

2. 错误捕获范围覆盖不全

你的try-catch仅包裹了建表和调用initPoint的代码,但wd.close()引发的异常是在initPoint执行完毕、框架后续操作数据库时触发的,不在捕获范围内,因此看不到错误码。


修正后的代码示例

第一个代码片段修正(移除手动关闭连接):

class SqliteHelper(context: Context?, name: String, version: Int) : SQLiteOpenHelper(context, name, null, version) {

    override fun onCreate(p0: SQLiteDatabase?) {
        try {
            p0?.execSQL("CREATE TABLE IF NOT EXISTS pointTable(id INTEGER PRIMARY KEY, pointValue INT)")
            p0?.let {
                initPoint(it)
            }
        } catch (err: Exception) {
            Log.d("test", err.toString())
            Log.d("test", err.stackTraceToString())
        }
    }

    fun initPoint(wd: SQLiteDatabase) {
        // 移除wd.close(),由SQLiteOpenHelper管理连接生命周期
        wd.execSQL("insert into pointTable(pointValue) values (0)")
    }
}

第二个代码片段补充完整错误捕获:

override fun onCreate(p0: SQLiteDatabase) {
    val sqlArray = arrayOf(
        "CREATE TABLE IF NOT EXISTS questionTable" +
                "(id INTEGER PRIMARY KEY," +
                " num INT," +
                " que TEXT," +
                " abcArr Text," +
                " opt1 Text, opt2 Text, opt3 Text, opt4 Text," +
                " ans INT," +
                " exp TEXT," +
                " examName TEXT," +
                " wrong INT, correct INT," +
                " part1 TEXT, part2 TEXT, part3 TEXT, part4 TEXT, part5 TEXT, part6 TEXT, part7 TEXT )",
        "CREATE TABLE IF NOT EXISTS examTable(examName TEXT, downloadDate TEXT, myApply INT)",
        "CREATE TABLE IF NOT EXISTS pointTable(id INTEGER PRIMARY KEY, pointValue INT)"

    )
    try {
        sqlArray.forEach {
            p0.execSQL(it)
        }
        initPoint(p0)
    } catch (err: Exception) {
        Log.d("test", err.toString())
        Log.d("test", err.stackTraceToString())
    }
}

private fun initPoint(wd: SQLiteDatabase){
    wd.execSQL("insert into pointTable(pointValue) values (5)")
}

额外排查建议

  • 所有数据库操作必须基于SQLiteOpenHelper提供的连接(回调方法传入的实例,或通过getWritableDatabase()/getReadableDatabase()获取的实例),禁止手动关闭这些连接。
  • 如果插入数据仍有问题,可改用insert方法替代execSQL,它会返回插入行ID(-1表示插入失败),便于更直观排查问题:
val values = ContentValues().apply {
    put("pointValue", 5)
}
val rowId = wd.insert("pointTable", null, values)
Log.d("test", "插入结果:$rowId")

内容的提问来源于stack exchange,提问作者조영민

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.12 09:21:01