Android.database.CursorWindowAllocationException: выделение окна курсора 2048 кб не удалось даже после закрытия курсора - программирование

Android.database.CursorWindowAllocationException: выделение окна курсора 2048 кб не удалось даже после закрытия курсора

Есть много вопросов о SO о CursorWindowAllocatoinException:

Все они предполагают, что курсор должен быть закрыт после использования. Но это не решило мою проблему. Вот мой код:

String query = "select serial from tbl1 union select serial from tbl2 union select serial from tbl3";
    SQLiteDatabase db = null;
    Cursor cur = null;
    try {
        SettingsDatabaseHelper dal = new SettingsDatabaseHelper(
                c);
        db = dal.getReadableDatabase();
        cur = db.rawQuery(query, null);
        int numRows = cur.getCount();
        if (numRows > 0) {
            cur.moveToFirst();

            int serialIdx = cur.getColumnIndexOrThrow("serial");
            for (boolean hasItem = cur.moveToFirst(); hasItem; hasItem = cur
                    .moveToNext()) {

                String serial = cur.getString(serialIdx);
                if (Validator.getInstance().isValidSerial(serial))
                    serials.add(serial);

            }
        }
    } finally {
        if (cur != null)
            cur.close();

        if (db != null)
            db.close();
    }

Я запускаю этот метод каждые несколько секунд. Через полчаса я получаю CursorWindowAllocationException в int numRows=cur.getCount();, а затем мое обслуживание прекращается.

Так как я закрываю курсор, может возникнуть проблема с моим классом Helper. Вот код:

public class SettingsDatabaseHelper extends SQLiteOpenHelper {

    private static final String DATABASE_NAME = "mydb.db";
    private static final int DATABASE_VERSION = 1;


    private static final String TBL_CREATE="create table...";



    public SettingsDatabaseHelper(Context context) {
        super(context, DATABASE_NAME, null, DATABASE_VERSION);
    }

    @Override
    public void onCreate(SQLiteDatabase database) {
        database.execSQL(TBL_CREATE);
    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        onCreate(db);
    }
}

Как я могу предотвратить выброс этого исключения?

4b9b3361

Ответ 1

Я запрашивал базу данных из службы. Когда я сделал это из активности, проблема никогда не повторялась.

Наряду с запросом я читал из последовательного порта в той же службе. Возможно, это и вызвало эту проблему. Однако, когда я использовал активность вместо службы, проблема больше не повторялась.

Ответ 2

У меня была такая же проблема в моем приложении при загрузке более 500 песен из хранилища носителей Android.

закрытие курсора не решит вашу проблему.

вы должны использовать AsyncTask.. внутри doInBackground метод записывает код для извлечения значений из курсора.

Открытый класс CursorLoader расширяет AsyncTask {

    @Override
    protected Void doInBackground(Void... params) {

        String query = "select serial from tbl1 union select serial from tbl2 union select serial from tbl3";
SQLiteDatabase db = null;
Cursor cur = null;
try {
    SettingsDatabaseHelper dal = new SettingsDatabaseHelper(
            c);
    db = dal.getReadableDatabase();
    cur = db.rawQuery(query, null);
    int numRows = cur.getCount();
    if (numRows > 0) {
        cur.moveToFirst();

        int serialIdx = cur.getColumnIndexOrThrow("serial");
        for (boolean hasItem = cur.moveToFirst(); hasItem; hasItem = cur
                .moveToNext()) {

            String serial = cur.getString(serialIdx);
            if (Validator.getInstance().isValidSerial(serial))
                serials.add(serial);

        }
    }
} finally {
    if (cur != null)
        cur.close();

    if (db != null)
        db.close();
}

        return null;
    }

    @Override
    protected void onPreExecute() {

    }



    @Override
    protected void onPostExecute(Void result) {


}

Ответ 3

У меня была та же проблема, в то время как я вызываю DATA BASE, в классе службы, используя цикл forever.

Мой код был похож:

service ()
 {
void run()
   {
     while(conditionisTrue)
       {
              db.getRecord();  //I remove this code from here and put it in the start of service c
        }
    }
 }