sqlite 如何调试CursorIndexOutOfBoundsException错误

laawzig2  于 11个月前  发布在  SQLite
关注(0)|答案(1)|浏览(135)

我是一个初学者,试图为我的学校项目构建一个健康应用程序
当我使用Android 11(API 30)时程序运行正常。当我使用Android高于11(API 30+)时发生错误。
发生错误的代码:

private fun refreshMe(){
    val helper = profileHelper(applicationContext)
    val db = helper.readableDatabase
    val rs = db.rawQuery("SELECT * FROM uProfile", null)

    rs.moveToLast()
    nama.text = rs.getString(1) //THE ERROR HAPPEN HERE
    umur.text = rs.getString(2)
    jk.text = rs.getString(3)
    data.text = rs.getString(4)
    kadarAu.text = rs.getString(5)
    kadarGd.text = rs.getString(6)
    kadarHb.text = rs.getString(7)
    kadarCh.text = rs.getString(8)
    kadarTdSis.text = rs.getString(9)
    kadarTdDia.text = rs.getString(10)
    rs.close()
    }

字符串
错误日志

FATAL EXCEPTION: main

Process: com.lhsproj.labhealthpocket, PID: 10098
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.lhsproj.labhealthpocket/com.lhsproj.labhealthpocket.MainActivity}: android.database.CursorIndexOutOfBoundsException: Index -1 requested, with a size of 0
    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3782)
    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3922)
    at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:103)
    at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:139)
    at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:96)
    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2443)
    at android.os.Handler.dispatchMessage(Handler.java:106)
    at android.os.Looper.loopOnce(Looper.java:205)
    at android.os.Looper.loop(Looper.java:294)
    at android.app.ActivityThread.main(ActivityThread.java:8177)
    at java.lang.reflect.Method.invoke(Native Method)
    at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:552)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:971)
Caused by: android.database.CursorIndexOutOfBoundsException: Index -1 requested, with a size of 0
    at android.database.AbstractCursor.checkPosition(AbstractCursor.java:521)
    at android.database.AbstractWindowedCursor.checkPosition(AbstractWindowedCursor.java:139)
    at android.database.AbstractWindowedCursor.getString(AbstractWindowedCursor.java:53)
    at com.lhsproj.labhealthpocket.MainActivity.refreshMe(MainActivity.kt:63)
    at com.lhsproj.labhealthpocket.MainActivity.onCreate(MainActivity.kt:251)
    at android.app.Activity.performCreate(Activity.java:8595)
    at android.app.Activity.performCreate(Activity.java:8573)
    at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1456)
    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3764)
    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3922) 
    at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:103) 
    at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:139) 
    at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:96) 
    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2443) 
    at android.os.Handler.dispatchMessage(Handler.java:106) 
    at android.os.Looper.loopOnce(Looper.java:205) 
    at android.os.Looper.loop(Looper.java:294) 
    at android.app.ActivityThread.main(ActivityThread.java:8177) 
    at java.lang.reflect.Method.invoke(Native Method) 
    at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:552) 
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:971) 


我之前尝试过Stack Overflow的几个解决方案,但我发现它们很难在我的项目中实现。

3okqufwl

3okqufwl1#

你应该ALWAYS检查移动是否成功(在你的例子中是moveToLast)。所有的move????方法都返回一个布尔值,如果移动成功则返回true,如果移动不成功则返回false。

  • -1\f25 moveToLastRowDID NOT MAKE THE MOVE-1(第一行之前)表示位置,因此moveToLastRow未移动
  • 另外**

通常不建议硬编码游标索引值。相反,建议通常使用Cursor的getColumnIndexgetColumnIndexOrThrow方法来确定列的索引及其有效性(如果列名无效或抛出IllegalArgumentException,则为-1)。
请参阅Cursor
所以你可以有一些沿着线:-

private fun refreshMe(){
    val helper = profileHelper(applicationContext)
    val db = helper.readableDatabase
    val rs = db.rawQuery("SELECT * FROM uProfile", null)

    val namaCI = rs.getColumnIndex("nama")
    val umrCI = rs.getColumnIndex("umur")
    val jkCI = rs.getColumnIndex("jk")
    val dataCI = rs.getColumnIndex("data")
    val kadarAuCI = rs.getColumnIndex("kadarAu")
    val kadarGdCI = rs.getColumnIndex("kadarGd")
    val kadarHbCI = rs.getColumnIndex("kadarHb")
    val kadarChCI = rs.getColumnIndex("kadaraCh")
    val kadarTdSisCI = rs.getColumnIndex("kadarTdSis")
    val kadarTdDiaCI = rs.getColumnIndex("kadarTdDia")
    val ok = namaCI >=0 && umrCI >= 0 && jkCI >= 0 && dataCI >0 && kadarAuCI >= 0 && kadarGdCI >= 0 && kadarHbCI >= 0 && kadarChCI >= 0 && kadarTdSisCI >= 0 && kadarTdDiaCI >= 0
    if (rs.moveToLast() && ok) {
        nama.text = rs.getString(namaCI) //THE ERROR HAPPEN HERE
        umur.text = rs.getString(umrCI)
        jk.text = rs.getString(jkCI)
        data.text = rs.getString(dataCI)
        kadarAu.text = rs.getString(kadarAuCI)
        kadarGd.text = rs.getString(kadarGdCI)
        kadarHb.text = rs.getString(kadarHbCI)
        kadarCh.text = rs.getString(kadarChCI)
        kadarTdSis.text = rs.getString(kadarTdSisCI)
        kadarTdDia.text = rs.getString(kadarTdDiaCI)
    } else {
        if (!ok) {
            /* INVALID COLUMN NAME */
        } else {
            /* NO DATA IN CURSOR */
        }
    }
    rs.close()
}

字符串

*列名是猜测的,因此可能不反映实际列名

要调试,您可以添加一个断点,例如在rs.moveToLast()行上,并在调试模式下运行,然后检查Windows中的光标,或者作为替代方案,使用DatabaseUtilsdumpCursor方法并检查日志,例如在val rs = db.rawQuery("SELECT * FROM uProfile", null)rs.moveToLast()行之间添加DatabaseUtils.dumpCursor(rs)行。

相关问题