Cursor window allocation of 2048 kb failed. # Open Cursors=1 (# cursors opened by this proc=1)
Asked Answered
T

1

7

I'm making an Kiosk app that use database. The app is running all time in foreground. The app have many threads that using one shared DataBaseHelper instance. the app works flawlessly but most of the time after 5 or 6 hour, I encounter these exceptions then app crashes:

E/DataBaseHelper﹕ Cursor window allocation of 2048 kb failed. # Open Cursors=1 (# cursors opened by this proc=1)

E/CursorWindow﹕ Could not allocate CursorWindow '/data/user/0/com.kios.frm/databases/YadProjectDB.db' of size 2097152 due to error -24.

E/SQLiteLog﹕ (14) cannot open file at line 30192 of [00bb9c9ce4]

E/SQLiteLog﹕ (14) statement aborts at 16: [SELECT number FROM sms LIMIT 5] unable to open database file

E/SQLiteQuery﹕ exception: unable to open database file (code 14);
query: SELECT number FROM sms LIMIT 5

E/SQLiteLog﹕ (14) os_unix.c:30192: (24)
open(/data/user/0/com.kiosk.frm/databases/YadProjectDB.db-journal)-

I closed cursor properly but still getting those exceptions. what are those exceptions? what is the cause of those exceptions?

MainActivity

private DataBaseHelper db = null; // Global     

MainActivity onCreate method:

db = new DataBaseHelper(this);

new Thread(new Runnable() {
@Override
public void run() {
    while (threadRunningFlag) {

    Cursor result = null;
    try {

        result = db.getData("SELECT " + DataBaseHelper.SMS_COLUMN_PHONE_NUMBER  + " FROM " + DataBaseHelper.SMS_TABLE_NAME + " LIMIT 5");
        if (result != null && result.getCount() > 0) {
            while (!result.isAfterLast()) {
                String phoneNumber = result.getString(result.getColumnIndex(DataBaseHelper.SMS_COLUMN_PHONE_NUMBER));
                // ...
                result.moveToNext();
            }
        }
    }catch (Exception e) {
        Log.e(TAG, "err->" + e.getLocalizedMessage());

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

        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            Log.e(TAG, e.getMessage());
        }
    }
}
}).start();

DataBaseHelper class:

public class DataBaseHelper extends SQLiteOpenHelper {

    private static final int DATABASE_VERSION = 1;
    public static final String DATABASE_NAME = "YadProjectDB.db";
    public static final String SMS_TABLE_NAME = "sms";
    public static final String SMS_COLUMN_PHONE_NUMBER = "number";
    public static final String SMS_COLUMN_SMS_TEXT = "message";

    public static final String BLACK_LIST_TABLE_NAME = "blackList";
    public static final String BLACK_LIST_COLUMN_ID = "id";
    public static final String BLACK_LIST_COLUMN_PHONE_NUMBER = "number";

    private final String TAG = "DataBaseHelper";

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

    }

    @Override
    public void onCreate( SQLiteDatabase db ) {
        String command = "CREATE TABLE "
                + SMS_TABLE_NAME
                + "("
                + SMS_COLUMN_PHONE_NUMBER + " TEXT,"
                + SMS_COLUMN_SMS_TEXT + " TEXT,"
                + ")";
        try {
            db.execSQL(command);
        }catch (Exception e) {
            Log.e(TAG, "err->" + e.getMessage());
        }

        command = "CREATE TABLE "
                + BLACK_LIST_TABLE_NAME
                + "("
                + BLACK_LIST_COLUMN_PHONE_NUMBER + " TEXT,"
                + ")";
        try {
            db.execSQL(command);
        }catch (Exception e) {
            Log.e(TAG, "err->" +  e.getMessage());
        }
    }

    public boolean insertToSms(String number, String message, String fileName, Integer uploadFlag, Integer blackList, Integer pictureFlag)
    {
        final SQLiteDatabase db = this.getWritableDatabase();
        ContentValues contentValues = new ContentValues();
        contentValues.put(SMS_COLUMN_PHONE_NUMBER, number);
        contentValues.put(SMS_COLUMN_SMS_TEXT, message);
        try {
            db.insert(SMS_TABLE_NAME, null, contentValues);
            return true;
        }catch (Exception e) {
            Log.e(TAG, "err->" + e.getMessage());
            return false;
        }
    }

    public Cursor getData(String query){
        final SQLiteDatabase db = getReadableDatabase();
        Cursor res = null;
        try {
            res = db.rawQuery(query, null);
            res.moveToFirst();
            return res;
        }catch (Exception e) {
            Log.e(TAG, "err->" + e.getMessage());
            if (res != null) {
                res.close();
                res = null;
            }
        }
        return null;
    }
}
Tactical answered 11/7, 2015 at 20:40 Comment(9)
what exactly do you want to achieve?Garrulous
cause of those exceptions and find the problemTactical
ok, why do you iterate over the Cursor?Garrulous
As you can see I'm retrieving data (like phoneNumber) of every rows.Tactical
check for any leaks you have in your Activity: it seems that CursorWindow cannot be allocated because of low memoryGarrulous
and why are you querying the db every second? it must be some flaw in your code logic...Garrulous
is it wrong to query db every second? in some threads i need to check data immediately.Tactical
it is your own db so you know when anything is inserted / updated / deleted, dont you?Garrulous
"is it wrong to query db every second?" that's why i asked: what do you want to achieve actually?Garrulous
M
10

This is looks the same issue as SQLite Android Database Cursor window allocation of 2048 kb failed

Your error says: "Open Cursors"

The answer in the above question explains it:

Most often the cause for this error are non closed cursors. Make sure you close all cursors after using them (even in the case of an error).

Cursor cursor = null;
try {
    cursor = db.query(...
    // do some work with the cursor here.
} finally {
    // this gets called even if there is an exception somewhere above
    if(cursor != null)
        cursor.close();
}
Meadors answered 11/7, 2015 at 20:55 Comment(6)
As you can see I'm closing Cursor properlyTactical
And how about Cursors in other places in your application? You might be leaking them elsewhere.Meadors
I'm using same code in other threads but with different logic. what about other exceptions?Tactical
What other exceptions? Are you leaking any other data? There could be some kind of data that you keep in memory and keeps on growing until 5-6 hours when it becomes too much and your next allocation (the Cursor creation) fails.Meadors
I'm populating db with incoming sms and do some operation on them. I tested app without any sms and empty db and again same exceptions occur.Tactical
the exceptions are just related to db.Tactical

© 2022 - 2024 — McMap. All rights reserved.