Połączenie SQLite wyciekło, chociaż wszystko jest zamknięte
Znalazłem wiele rzeczy takich jak close the connection
i close the cursor
, ale robię to wszystko. Mimo to połączenie SQLite przecieka i dostaję takie Ostrzeżenie:
A SQLiteConnection object for database was leaked!
Mam menedżera baz danych, który nazywam w moich działaniach następującym kodem:
DatabaseManager dbm = new DatabaseManager(this);
Kod mojej klasy menedżera baz danych następuje teraz:
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();
}
}
Kiedy wywołuję metodę bazodanową, robię następujące rzeczy:
public Object getData() {
open();
//... database operations take place ...
close();
return data;
}
Ale jak już mówiłem, nadal dostaję ostrzeżenie o wycieku połączenia SQLite.
Kim jestem źle robisz?
2 answers
Pogrubiona czcionka w cytacie odpowiada tej części Twojego kodu:
private DatabaseManager open() throws SQLException {
dbHelper = new DatabaseHelper(context);
db = dbHelper.getWritableDatabase();
Od: http://www.androiddesignpatterns.com/2012/05/correctly-managing-your-sqlite-database.html
Podejście # 1: Użyj abstrakcyjnej fabryki, aby utworzyć instancję SQLiteOpenHelper
Zadeklaruj swój Pomocnik bazy danych jako statyczną zmienną instancji i użyj Abstrakcyjny wzór fabryczny gwarantujący własność Singletona. Na przykładowy kod poniżej powinien dać ci dobry pomysł o tym, jak przejść poprawne zaprojektowanie klasy bazy danych.
Statyczna metoda getinstance zapewnia, że tylko jeden Baza danych zawsze będzie istnieć w danym momencie. Jeśli mInstance obiekt nie został zainicjowany, zostanie utworzony. Jeśli ktoś ma już został utworzony, a następnie po prostu zostanie zwrócony.
powinieneś nie inicjalizuje obiektu pomocniczego używając znew DatabaseHelper(context)
.
Zamiast tego Zawsze używajDatabaseHelper.getInstance(context)
, ponieważ gwarantuje że tylko jeden Pomocnik bazy danych będzie istniał w całym cyklu życia aplikacji.
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);
}
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-02-23 10:33:16
private void method() {
Cursor cursor = query();
if (flag == false) { // WRONG: return before close()
return;
}
cursor.close();
}
Dobra praktyka powinna wyglądać tak:
private void method() {
Cursor cursor = null;
try {
cursor = query();
} finally {
if (cursor != null)
cursor.close(); // RIGHT: ensure resource is always recovered
}
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-01-23 10:40:28