【问题标题】:Android SQLite Database fails to select a row with a large value, throws IllegalStateExceptionAndroid SQLite 数据库选择大值行失败,抛出 IllegalStateException
【发布时间】:2012-09-02 02:47:29
【问题描述】:

我创建了下面的类,用于将数据保存到 SQLite 数据库。如您所见,它只是一个键/值映射。 KEY 是 TEXT 字段,VALUE 是 BLOB。

它完美地工作,除了在一种情况下: 我使用“add”来添加一个长度约为 2,500,000 个字符的字符串。事实上,它是一个 JSON 编码的字符串(我也尝试过应用 javascript 样式的 encodeURIComponent,以确保没有非法字符干扰)。

在这种情况下,值被成功添加(没有抛出错误,add() 返回 true)。但是,当我之后立即调用 get(key) 时,从 cursor.getString(0) 中抛出 IllegalStateException。

具体来说:

"Couldn't read row 0, col 0 from CursorWindow.  Make sure the Cursor is initialized correctly before accessing data from it." (id=830026207728) 

我检查了游标对象,没有发现任何问题(mCount==1、mColumns==String[1] 等)。

class DatabaseHandler extends SQLiteOpenHelper {

    // All Static variables
    // Database Version
    private static final int DATABASE_VERSION = 2;

    // Contacts Table Columns names
    private static final String KEY_KEY = "key";
    private static final String KEY_VAL = "value";

    public DatabaseHandler(Context context) {
        super(context, Defines.DATA_PREFIX, null, DATABASE_VERSION);
    }

    public String getTableName() {
        return "storage";
    }

    // Creating Tables
    @Override
    public void onCreate(SQLiteDatabase db) {
        String q = "CREATE TABLE " + this.getTableName() + "(" + KEY_KEY + " TEXT PRIMARY KEY," + KEY_VAL + " BLOB" + ")";
        db.execSQL(q);
    }

    // Upgrading database
    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        // Drop older table if existed
        db.execSQL("DROP TABLE IF EXISTS " + this.getTableName());

        // Create tables again
        onCreate(db);
    }

    boolean add(String key, String value) {
        SQLiteDatabase db = this.getWritableDatabase();

        ContentValues values = new ContentValues();
        values.put(KEY_KEY, key); // Contact Name
        values.put(KEY_VAL, value); // Contact Phone

        // Inserting Row
        long res = db.insertOrThrow(this.getTableName(), null, values);
        db.close(); // Closing database connection
        return res >= 0;
    }

    String get(String key) {
        SQLiteDatabase db = this.getReadableDatabase();

        Cursor cursor = db.query(this.getTableName(), new String[] { KEY_VAL }, KEY_KEY + "=?", new String[] { key }, null, null, null, null);
        if (cursor != null)
            cursor.moveToFirst();

        if(cursor == null)
            return null;

        String ret = null;
        try {
            ret = cursor.getString(0);
        } catch(CursorIndexOutOfBoundsException e) {
            ret = null;
        } catch(IllegalStateException e) {
            ret = null;
        }
        cursor.close();
        return ret;
    }

    int count(String key) {
        String countQuery = "SELECT  * FROM " + this.getTableName()+" WHERE "+KEY_KEY+" = ?";
        SQLiteDatabase db = this.getReadableDatabase();
        Cursor cursor = db.rawQuery(countQuery, new String[] { key });
        int ret = cursor.getCount();;
        cursor.close();

        // return count
        return ret;
    }

    void delete(String key) {
        SQLiteDatabase db = this.getWritableDatabase();
        db.delete(this.getTableName(), KEY_KEY + " = ?", new String[] { key });
        db.close();
    }

    int update(String key, String value)
    {
        SQLiteDatabase db = this.getWritableDatabase();

        ContentValues values = new ContentValues();
        values.put(KEY_KEY, key);
        values.put(KEY_VAL, value);

        // updating row
        return db.update(this.getTableName(), values, KEY_KEY + " = ?", new String[] { key });
    }
}

【问题讨论】:

    标签: android sqlite


    【解决方案1】:

    经过进一步调查,控制台窗口告诉我“光标窗口”已满,例如空间不足。看到这个帖子:Android: Cursor Window is full

    我的解决方案是“分块”数据。例如,“add”函数检测字符串是否大于固定长度,在这种情况下,它会为字符串存储多个条目(使用很多行)。然后“get”函数检测到这一点并重新组装块。

    【讨论】:

      猜你喜欢
      • 2020-10-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-05-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多