【问题标题】:Error CursorIndexOutOfBoundsException on SQLite when fast querying快速查询时 SQLite 上的错误 CursorIndexOutOfBoundsException
【发布时间】:2011-10-14 03:32:22
【问题描述】:

我使用字段 ID 和 8 个字段字符串(有些可以为空)从 SQLite 查询。 我有一个 getSearchedItemsFromSQLite 方法,只要 EditText 对象(自动搜索)发生更改状态,就会触发该方法,并且这些错误消息随机出现,但应用程序根本没有崩溃。

    07-27 18:24:52.619: ERROR/AndroidRuntime(1173): ERROR: thread attach failed
    07-27 18:24:55.188: ERROR/AndroidRuntime(1184): ERROR: thread attach failed
    07-27 18:25:18.649: ERROR/GuitarTabs(1191): getSearchedItemsFromSQLite: Handler for DB + cursor: Index 6 requested, with a size of 6


    07-27 18:25:18.659: WARN/System.err(1191): android.database.CursorIndexOutOfBoundsException: Index 6 requested, with a size of 6
    07-27 18:25:18.889: WARN/System.err(1191):     at android.database.AbstractCursor.checkPosition(AbstractCursor.java:580)
    07-27 18:25:18.889: WARN/System.err(1191):     at android.database.AbstractWindowedCursor.checkPosition(AbstractWindowedCursor.java:214)
    07-27 18:25:18.889: WARN/System.err(1191):     at android.database.AbstractWindowedCursor.getString(AbstractWindowedCursor.java:41)
    07-27 18:25:18.889: WARN/System.err(1191):     at com.package.project.activity.ItemBrowserActivity.getSearchedItemsFromSQLite(ItemBrowserActivity.java:351)
    07-27 18:25:18.889: WARN/System.err(1191):     at com.package.project.activity.ItemBrowserActivity$AppInitialization.doInBackground(ItemBrowserActivity.java:199)
    07-27 18:25:18.889: WARN/System.err(1191):     at com.package.project.activity.ItemBrowserActivity$AppInitialization.doInBackground(ItemBrowserActivity.java:1)
    07-27 18:25:18.889: WARN/System.err(1191):     at android.os.AsyncTask$2.call(AsyncTask.java:185)
    07-27 18:25:18.899: WARN/System.err(1191):     at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:305)
    07-27 18:25:18.909: WARN/System.err(1191):     at java.util.concurrent.FutureTask.run(FutureTask.java:137)
    07-27 18:25:18.909: WARN/System.err(1191):     at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1068)
    07-27 18:25:18.909: WARN/System.err(1191):     at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:561)
    07-27 18:25:18.909: WARN/System.err(1191):     at java.lang.Thread.run(Thread.java:1096)

我该如何解决这个问题?

这是该方法的代码sn-p:

        dbHelper.open();
        cursor = dbHelper.fetchAllTabs(fetchMethod);
        startManagingCursor(cursor);
        if(cursor != null && cursor.getCount() > 0) {
            if(cursor.moveToFirst()) {
                while (cursor.isAfterLast() == false) {
                    if(cursor.getColumnCount() > 0) {
                        Log.i(logAppName, "/ - Column count is:  " + cursor.getColumnCount());
                        if(!cursor.isNull(0) && !cursor.isNull(1)) {
                            if(!cursor.isNull(0)) {
                                ListedItem tab = new ListedItem();
                                tab.setSongID(cursor.getInt(0));
                                if(!cursor.isNull(1)) tab.setTitle(cursor.getString(1));
                                if(!cursor.isNull(2)) tab.setArtist(cursor.getString(2));
                                if(!cursor.isNull(3)) tab.setDifficulty(cursor.getString(3));
                                if(!cursor.isNull(4)) tab.setGenre(cursor.getString(4));
                                if(!cursor.isNull(5)) tab.setFilename(cursor.getString(5));
                                if(!cursor.isNull(6)) tab.setFileformat(cursor.getString(6));
                                if(!cursor.isNull(7)) tab.setSource(cursor.getString(7));
                                if(!cursor.isNull(8)) tab.setDeleted(cursor.getString(8));
                                if(Integer.parseInt(tab.getDeleted()) == 0)
                                    ret.add(tab);
                                else 
                                    Log.i(logAppName, "Not adding tab: " + tab.getSongTitle() + " (" + tab.getSongFilename() + ") " + "since it's already deleted.");
                                cursor.moveToNext();
                            } else {
                                Log.i(logAppName, "x - ID is null.");
                            }
                        } else {
                            Log.i(logAppName, "x - Either id or title is null.");
                        }
                    } else {
                        Log.i(logAppName, "x - Column count is:  " + cursor.getColumnCount());
                    }
                }
            }      
            if(cursor != null)
                cursor.close();

【问题讨论】:

  • 嗯,根据错误信息,您的光标尝试访问索引 6,但您的光标仅包含索引 [0,5]。检查您的查询,看看它实际上返回了您需要的列数。你的输出是什么: Log.i(logAppName, "/ - Column count is: " + cursor.getColumnCount())
  • 我认为这背后的原因是,在快速查询中,当我在 editText 中输入 a then u 时,它总是在 editText 的值发生变化时调用查询方法,因此,方法在被调用时永远不会真正完成处理再次。这个错误只发生在模拟器上,我已经在设备上测试过了,我根本无法重现这个错误。涉及到 SQLite 的模拟器有什么限制吗?

标签: java android sqlite cursor indexoutofboundsexception


【解决方案1】:

我添加了这些条件:

if ( cursor != null && cursor.getCount() > 0 ) { 
    totalRows = cursor.getCount();
if(cursor.moveToFirst()) {
    while (cursor.isAfterLast() == false) {
        if(cursor.getColumnCount() > 0) {
               ...

之后,我添加了一个睡眠线程,让前一个进程先完成,然后再通过另一个进程:

private boolean processing = false;
...

int ctr = 0;
// added fix to avoid error on cursor
while(processing) {
    try {
    Log.i(logAppName, "Still processing. Count: " + ctr + ". Is processing? " + processing);
        ctr++;
        Thread.sleep(500);
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
    if(ctr > 5) {
        break;
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-05-03
    • 1970-01-01
    • 2018-05-28
    • 1970-01-01
    • 2012-05-19
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多