android - cursor.moveToNext() 抛出 CursorWindowAllocationException

标签 android sqlite kotlin android-sqlite

由于这个异常,我遇到了几次崩溃,但无法在我自己的任何设备/模拟器上复制它。

来自 google play console 的堆栈跟踪

  android.database.CursorWindowAllocationException: 
  at android.database.CursorWindow.<init> (CursorWindow.java:108)
  at android.database.AbstractWindowedCursor.clearOrCreateWindow (AbstractWindowedCursor.java:198)
  at android.database.sqlite.SQLiteCursor.fillWindow (SQLiteCursor.java:138)
  at android.database.sqlite.SQLiteCursor.getCount (SQLiteCursor.java:132)
  at android.database.AbstractCursor.moveToPosition (AbstractCursor.java:220)
  at android.database.AbstractCursor.moveToNext (AbstractCursor.java:269)
  at rpuls.yatzysheets.DBController.getGameTime (DBController.kt:264)
  at rpuls.yatzysheets.PreviousGames$onCreateView$1.invoke (PreviousGames.kt:78)
  at rpuls.yatzysheets.PreviousGames$onCreateView$1.invoke (PreviousGames.kt:23)
  at org.jetbrains.anko.support.v4.SupportKt.UI (Support.kt:62)
  at rpuls.yatzysheets.PreviousGames.onCreateView (PreviousGames.kt:33)
  at android.support.v4.app.Fragment.performCreateView (Fragment.java:2337)
  at android.support.v4.app.FragmentManagerImpl.moveToState (FragmentManager.java:1419)
  at android.support.v4.app.FragmentManagerImpl.moveFragmentToExpectedState (FragmentManager.java:1740)
  at android.support.v4.app.FragmentManagerImpl.moveToState (FragmentManager.java:1809)
  at android.support.v4.app.BackStackRecord.executeOps (BackStackRecord.java:799)
  at android.support.v4.app.FragmentManagerImpl.executeOps (FragmentManager.java:2580)
  at android.support.v4.app.FragmentManagerImpl.executeOpsTogether (FragmentManager.java:2367)
  at android.support.v4.app.FragmentManagerImpl.removeRedundantOperationsAndExecute (FragmentManager.java:2322)
  at android.support.v4.app.FragmentManagerImpl.execPendingActions (FragmentManager.java:2229)
  at android.support.v4.app.FragmentManagerImpl$1.run (FragmentManager.java:700)
  at android.os.Handler.handleCallback (Handler.java:790)
  at android.os.Handler.dispatchMessage (Handler.java:99)
  at android.os.Looper.loop (Looper.java:164)
  at android.app.ActivityThread.main (ActivityThread.java:6651)
  at java.lang.reflect.Method.invoke (Native Method)
  at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run (RuntimeInit.java:438)
  at com.android.internal.os.ZygoteInit.main (ZygoteInit.java:810)

抛出它的函数

fun getGameTime(gameId: Long): String{
    val db = this.readableDatabase
    val cursor = db.rawQuery("SELECT ${gameTable.timestamp} FROM ${gameTable.table} WHERE ${gameTable.id} = ${gameId}", null)
    var result = ""
    if(cursor.moveToNext()){
        result = cursor.getString(cursor.getColumnIndex(gameTable.timestamp))
    }
    db.close()
    return result
}

当我用谷歌搜索 CursorWindowAllocationException 时,几乎每个结果都与未关闭光标和内存不足导致 moveToNext() 抛出异常有关。

然而,在我得到的堆栈跟踪中,没有任何关于内存不足的信息,我相信我的游标会关闭,因为它所在的 readableDatabase 数据库已关闭?

发生错误的设备

基本上是一款配备 2GB 内存的现代手机。它在过去 60 天内发生过一次,但我几个月前就见过它。

该应用每天大约在 40 台设备上运行,因此在 2400 次运行中有 1 次崩溃 - 不多,但我想知道为什么会这样。

最佳答案

我会说你的作品 cursor 有点奇怪。而且我不确定 cursor 是否会在数据库关闭时关闭。无论如何,我建议这样做:

if (cursor.moveToFirst()) {
    result = cursor.getString(cursor.getColumnIndex(gameTable.timestamp))
}
cursor.close()
db.close()

关于android - cursor.moveToNext() 抛出 CursorWindowAllocationException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54865761/

相关文章:

sqlite - 转储不带自动生成列(例如 id)的 SQLite 表/数据库

android - 如何统计 Kotlin Android 中的字数?

线性布局的Android幻灯片动画

android - 具有两个可绘制对象的具有遮蔽效果的自定义搜索栏?

android - 由于gradle问题,如何修复 “Unable to load class ' Dagger 。

android - 有没有像w3school这样可以在线练习android编程的网站?

android - 弄清楚sqlite android查询的麻烦

java - Android 数据库 SQLite 平均值

kotlin - 如何让 Dokka 生成可部署的 github wiki?

java - Java 中的联合类型