android – 光标窗口分配2048 kb失败. #Open Cursors = 1(此proc = 1打开的#游标)

我正在制作一个使用数据库的Kiosk应用程序.该应用程序一直在前台运行.该应用程序有许多使用一个共享DataBaseHelper实例的线程.该应用程序完美无缺,但大多数时间在5或6小时后,我遇到这些异常,然后应用程序崩溃:

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)-

我正确关闭了光标,但仍然获得了这些异常.那些例外是什么?这些例外的原因是什么?

主要活动

private DataBaseHelper db = null; // Global

MainActivity onCreate方法:

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类:

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,"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,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;
    }
}

解决方法

这与 SQLite Android Database Cursor window allocation of 2048 kb failed看起来相同

你的错误说:“打开游标”

上述问题的答案解释了:

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();
}

相关文章

ADB Remote ATV Android TV 的遥控器,基于 ADB Shell 命令 ...
使用Flutter自带的SearchDelegate组件实现搜索界面,通过魔改...
上篇文章讲解了怎么使用Kotlin的协程配合Retrofit发起网络请...
安卓开发——WebView+Recyclerview文章详情页,解决高度...
Android 如何解决dialog弹出时无法捕捉Activity的back事件 在...