Android SQLite просочился

У меня проблема с обработчиком sql

A SQLiteConnection object for database '/data/data/.../databases/queueManager' was leaked! Please fix your application to end transactions in progress properly and to close the database when it is no longer needed. 

Взято из учебника Androidhive и настроено для моего использования

Таблица выглядит

 + ----------------------------------------------------------- + : DATABASE_ID : DATABASE_QID : DATABASE_QUEUE : DATABASE_DATE : + ----------------------------------------------------------- + 

Код

  DBQueue searchDBqid(int id) { SQLiteDatabase db = this.getReadableDatabase(); String selectQuery = "SELECT * FROM " + TABLE_QUEUE + " WHERE " + DATABASE_QID + " = " + id; Cursor cursornum = db.rawQuery(selectQuery, null); int dk = cursornum.getCount(); cursornum.close(); if (dk >0) { Cursor cursor = db.query(TABLE_QUEUE, new String[] { DATABASE_ID, DATABASE_QID, DATABASE_QUEUE, DATABASE_DATE }, DATABASE_QID + "=?", new String[] { String.valueOf(id) }, null, null, null, null); if (cursor != null) cursor.moveToFirst(); DBQueue dbqueue = new DBQueue(Integer.parseInt(cursor.getString(0)), cursor.getString(1), cursor.getString(2), cursor.getString(3)); return dbqueue; } db.close(); return null; } DBQueue getDBQueue(int id) { SQLiteDatabase db = this.getReadableDatabase(); Cursor cursor = db.query(TABLE_QUEUE, new String[] { DATABASE_ID, DATABASE_QID, DATABASE_QUEUE }, DATABASE_ID + "=?", new String[] { String.valueOf(id) }, null, null, null, null); if (cursor != null) cursor.moveToFirst(); DBQueue dbqueue = new DBQueue(Integer.parseInt(cursor.getString(0)), cursor.getString(1), cursor.getString(2), cursor.getString(3)); return dbqueue; } public String getAllqid() { Time today = new Time(Time.getCurrentTimezone()); today.setToNow(); String selectQuery = "SELECT * FROM " + TABLE_QUEUE + " WHERE " + DATABASE_DATE + " = '" + today.format("%d %m %Y") + "'"; SQLiteDatabase db = this.getWritableDatabase(); Cursor cursor = db.rawQuery(selectQuery, null); StringBuilder sb = new StringBuilder(); if (cursor.moveToFirst()) { do { if (sb.length() > 0) sb.append(','); sb.append(cursor.getString(1)); } while (cursor.moveToNext()); } String result = sb.toString(); return result; } public void deleteDatedDBQueue() { Time today = new Time(Time.getCurrentTimezone()); today.setToNow(); String selectQuery = "SELECT * FROM " + TABLE_QUEUE + " WHERE " + DATABASE_DATE + " != '" + today.format("%d %m %Y") + "'"; ; SQLiteDatabase db = this.getWritableDatabase(); Cursor cursor = db.rawQuery(selectQuery, null); if (cursor.moveToFirst()) { do { db.delete(TABLE_QUEUE, DATABASE_ID + " = ?", new String[] { String.valueOf(Integer.parseInt(cursor.getString(0))) }); } while (cursor.moveToNext()); } db.close(); } public int getDBQueueCount() { String countQuery = "SELECT * FROM " + TABLE_QUEUE; SQLiteDatabase db = this.getReadableDatabase(); Cursor cursor = db.rawQuery(countQuery, null); cursor.close(); return cursor.getCount(); } } 

Может кто-нибудь, пожалуйста, скажите мне, как исправить эту утечку?

Полный код: http://ijailbreak.me/databasehandler.txt

Каждый Cursor должен быть закрыт, когда вы закончите с ним. Традиционный способ сделать это:

 Cursor cursor = db.query(...); try { // read data from the cursor in here } finally { cursor.close(); } 

Но теперь, используя try-with-resources , это может быть намного более кратким:

 try (Cursor cursor = db.query(...)) { // read data from the cursor in here } 

Вы забыли закрыть свои курсоры несколько раз, убедитесь, что вы всегда закрываете курсор, когда делаете это.

Например, второй запрос не закрывает курсор, у меня есть TODO'd для ясности

Также вы не закрываете SQLiteDatabase после выполнения в getDBQueue , getAllqid и getDBQueueCount , если вы измените свой дизайн, чтобы сделать ваш SQLiteOpenHelper тогда вам не нужно закрывать SQLiteDatabase и избегать утечки

  DBQueue searchDBqid(int id) { SQLiteDatabase db = this.getReadableDatabase(); String selectQuery = "SELECT * FROM " + TABLE_QUEUE + " WHERE " + DATABASE_QID + " = " + id; Cursor cursornum = db.rawQuery(selectQuery, null); int dk = cursornum.getCount(); cursornum.close(); if (dk >0) { // TODO: Close this cursor! Cursor cursor = db.query(TABLE_QUEUE, new String[] { DATABASE_ID, DATABASE_QID, DATABASE_QUEUE, DATABASE_DATE }, DATABASE_QID + "=?", new String[] { String.valueOf(id) }, null, null, null, null); if (cursor != null) cursor.moveToFirst(); DBQueue dbqueue = new DBQueue(Integer.parseInt(cursor.getString(0)), cursor.getString(1), cursor.getString(2), cursor.getString(3)); return dbqueue; } db.close(); return null; } 

Каждый раз, когда вы открываете базу данных (читаемую или записываемую), а курсор, который использует ресурсы памяти, должен быть освобожден, используя «.close ();» После того, как его использование заканчивается в каждой функции базы данных, например:

  if (cursor != null) cursor.moveToFirst(); DBQueue dbqueue = new DBQueue(Integer.parseInt(cursor.getString(0)), cursor.getString(1), cursor.getString(2), cursor.getString(3)); return dbqueue; } cursor.close(); db.close(); return null; } DBQueue getDBQueue(int id) { SQLiteDatabase db = this.getReadableDatabase(); Cursor cursor = db.query(TABLE_QUEUE, new String[] { DATABASE_ID, DATABASE_QID, DATABASE_QUEUE }, DATABASE_ID + "=?", new String[] { String.valueOf(id) }, null, null, null, null); if (cursor != null) cursor.moveToFirst(); DBQueue dbqueue = new DBQueue(Integer.parseInt(cursor.getString(0)), cursor.getString(1), cursor.getString(2), cursor.getString(3)); cursor.close(); db.close(); return dbqueue; } 

и так далее….!!

Первый раз открыть базу данных и в последний раз поставить этот код.

  @Override protected void onDestroy() { // TODO Auto-generated method stub mdb.close(); super.onDestroy(); } 
Intereting Posts
Размер изображения увеличивается при преобразовании из jpg в webp с качеством 100 Как перенести API Twitter с v1 на v1.1? Ошибка libusb_open_device_with_vid_pid при попытке доступа к USB-устройству Автоматическое зеркальное отображение макета в левом левом углу с леденцом Android: добавление приложения в список «установить изображение как» Создание файла заголовка для класса активности android Идентификатор ресурса Android для телефонов с высоким разрешением и телевизоров Google Пользовательское расширение файла в Android Позиция активности в стеке действий Невозможно создать обработчик внутри потока, который не вызвал Looper.prepare () Как определить сериализацию с помощью GSON? Объявление Android с выпуском Google plus при первом входе в систему Политика безопасности контента WebView Как сделать мобильную веб-страницу на Android? В libgdx на Android, как мне сохранить состояние игры в случае, если приложение убито?