Соединение SQLite просочилось, хотя все закрыто

Я нашел много таких вещей, как close the connection и close the cursor , но я все это делаю. Однако соединение SQLite протекает, и я получаю предупреждение:

 A SQLiteConnection object for database was leaked! 

У меня есть менеджер баз данных, который я вызываю в своей деятельности со следующим кодом:

 DatabaseManager dbm = new DatabaseManager(this); 

Ниже приведен код моего менеджера баз данных:

 public class DatabaseManager { private static final int DATABASE_VERSION = 9; private static final String DATABASE_NAME = "MyApp"; private Context context = null; private DatabaseHelper dbHelper = null; private SQLiteDatabase db = null; public static class DatabaseHelper extends SQLiteOpenHelper { public DatabaseHelper(Context context) { super(context, DATABASE_NAME, null, DATABASE_VERSION); } @Override public void onCreate(SQLiteDatabase db) { //create database tables } @Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { //destroy and recreate them } } public DatabaseManager(Context ctx) { this.context = ctx; } private DatabaseManager open() throws SQLException { dbHelper = new DatabaseHelper(context); db = dbHelper.getWritableDatabase(); if (!db.isReadOnly()) { db.execSQL("PRAGMA foreign_keys = ON;"); } return this; } private void close() { dbHelper.close(); } } 

Когда я вызываю метод базы данных, я делаю следующее:

 public Object getData() { open(); //... database operations take place ... close(); return data; } 

Но, как я уже сказал, я все еще получаю это сообщение о утечке SQLite.

Что я делаю не так?

Solutions Collecting From Web of "Соединение SQLite просочилось, хотя все закрыто"

Жирный шрифт в цитате соответствует этой части вашего кода:

 private DatabaseManager open() throws SQLException { dbHelper = new DatabaseHelper(context); db = dbHelper.getWritableDatabase(); 

От: http://www.androiddesignpatterns.com/2012/05/correctly-managing-your-sqlite-database.html

Подход №1: использование абстрактной фабрики для создания экземпляра SQLiteOpenHelper

Объявите свой помощник базы данных как статическую переменную экземпляра и используйте шаблон Abstract Factory, чтобы гарантировать свойство singleton. Пример кода ниже должен дать вам представление о том, как правильно спроектировать класс DatabaseHelper.

Статический метод getInstance фабрики гарантирует, что в любой момент времени будет существовать только один DatabaseHelper. Если объект mInstance не был инициализирован, он будет создан. Если он уже был создан, он просто будет возвращен.

Вы не должны инициализировать свой вспомогательный объект, используя new DatabaseHelper(context) .
Вместо этого всегда используйте DatabaseHelper.getInstance(context) , поскольку он гарантирует, что только один помощник базы данных будет существовать на протяжении всего жизненного цикла приложения.

 public static class DatabaseHelper extends SQLiteOpenHelper { private static DatabaseHelper mInstance = null; private static final String DATABASE_NAME = "database_name"; private static final String DATABASE_TABLE = "table_name"; private static final int DATABASE_VERSION = 1; public static DatabaseHelper getInstance(Context ctx) { // Use the application context, which will ensure that you // don't accidentally leak an Activity's context. // See this article for more information: http://bit.ly/6LRzfx if (mInstance == null) { mInstance = new DatabaseHelper(ctx.getApplicationContext()); } return mInstance; } /** * Constructor should be private to prevent direct instantiation. * make call to static factory method "getInstance()" instead. */ private DatabaseHelper(Context ctx) { super(ctx, DATABASE_NAME, null, DATABASE_VERSION); } }