android游标指示行计数1但抛出异常0行找到

时间:2016-06-13 12:57:00

标签: android sqlite

您是否有过光标告诉您它有数据但在尝试访问该数据时会立即抛出异常?没有?我有,我在我的智慧结束。 Blow是抛出异常的代码。在它下面我将添加Log Cat输出。

protected void setValue(String qVal) {
    StringTokenizer tokenizer = new StringTokenizer(qVal,"|");
    String first = tokenizer.nextToken();
    if(first.equalsIgnoreCase("0"))
        return;
    String searchID = tokenizer.nextToken();
    String [] cols = {TempImageEntry.RawData, TempImageEntry.FileName};
    String selection = TempImageEntry.ID + "=" + searchID;
    Cursor cursor = mDatabase.getReadableDatabase().query(TempImageEntry.TABLE_NAME,cols,selection,null,null,null,null);
    boolean check = cursor.moveToFirst();
    if(!check)
    {
        cursor.close();
        Log.e(LOG_TAG,"Could not find image data!");
        return;
    }
    int temp1 = cursor.getColumnIndex(TempImageEntry.FileName);
    int count = cursor.getCount();
    Log.d(LOG_TAG,"Count:"+count);
    String FName = cursor.getString(temp1);
    byte [] rawData = cursor.getBlob(cursor.getColumnIndex(TempImageEntry.RawData));
    cursor.close();
    setImageData(rawData,FName);
    Log.d(LOG_TAG,"parsed image data");
}

Loggat输出:

D/ImageHelper: Count:1 E/CursorWindow: Failed to read row 0, column 1 from a CursorWindow which has 0 rows, 2 columns. D/AndroidRuntime: Shutting down VM W/dalvikvm: threadid=1: thread exiting with uncaught exception (group=0x40e94ac8) E/AndroidRuntime: FATAL EXCEPTION: main java.lang.IllegalStateException: Couldn't read row 0, col 1 from CursorWindow. Make sure the Cursor is initialized correctly before accessing data from it.

我尝试过彻底重建代码。无济于事。 我从设备中提取数据库,在SQLite浏览器中打开它,输入由android生成的相同查询,然后我得到了数据。 应用程序中的每个其他游标都遵循这个完全相同的逻辑路径,它们都可以工作 我甚至将一些变量从内联变为temp,以查看它们在运行时的样子。

感谢您提供任何建议

1 个答案:

答案 0 :(得分:0)

谢谢大家的帮助。 原来光标窗口确实不允许查询中大于1 MB的数据。 贝娄是现在以零碎的方式提取文件的代码。

private byte[] ProcessRawData(String searchID) {
    String selection = TempImageEntry.ID + "=" + searchID;
    String [] cols;
    int count = 0;
    byte [] rawData = new byte[0];
    Long tracker = BlobSize;//use a generic length function of your choice
    do {
        cols = new String [] {"substr(" + TempImageEntry.RawData + ","+(1 + 1000000L * count)+",1000000)"};
        Cursor cursor = mDatabase.getReadableDatabase().query(TempImageEntry.TABLE_NAME,cols,selection,null,null,null,null);
        if(!cursor.moveToFirst())
        {
            cursor.close();
            Log.e(LOG_TAG,"Serious Error");
            return rawData;
        }
        byte [] theBit = cursor.getBlob(0);//get the current chunk
        cursor.close();
        byte[] c = new byte[rawData.length + theBit.length];//make room for the new chunk
        System.arraycopy(rawData, 0, c, 0, rawData.length);//copy old chunk into the new room
        System.arraycopy(theBit, 0, c, rawData.length, theBit.length);//copy the new chunk into the room made for the total
        rawData = c;//set the new collected as the main
        count++;
        tracker -= 1000000L;
    }while (tracker> 1000000L);
    cols = new String[]{"substr(" + TempImageEntry.RawData + "," + (1 + 1000000L * count) + "," + tracker + ")"};
    Cursor cursor = mDatabase.getReadableDatabase().query(TempImageEntry.TABLE_NAME, cols, selection, null, null, null, null);
    if (!cursor.moveToFirst()) {
        cursor.close();
        Log.e(LOG_TAG, "Serious Error");
        return rawData;
    }
    byte[] theBit = cursor.getBlob(0);
    cursor.close();
    byte[] c = new byte[rawData.length + theBit.length];
    System.arraycopy(rawData, 0, c, 0, rawData.length);
    System.arraycopy(theBit, 0, c, rawData.length, theBit.length);
    rawData = c;

    return rawData;
}

也许没有最好的方法,但它的功能。 是的,存储blob可能不是最好的方法,因为我们可以写入磁盘,但我遇到了android文件丢失的问题,我们希望在不再需要时明确销毁文件。