2014-02-01 1 views
9

Я делаю свое первое приложение для Android, и сначала я взял несколько учебников по sqlite, которые научили меня использовать databaseHelper, который расширяет SQLiteOpenHelper. Поэтому мой DatabaseHelper расширяет SQLiteOpenHelper. Я получаю предупреждение об утечке соединения sqlite в Logcat, поэтому мне бы хотелось, чтобы некоторые советы о том, что делать, чтобы исправить это.Объект соединения SQLite просочился - Android

Я получаю эту ошибку:

02-01 21:39:50.740: W/SQLiteConnectionPool(32061): A SQLiteConnection object for database '/data/data/com.btf271.fashionassistant/databases/clothingManager' was leaked! Please fix your application to end transactions in progress properly and to close the database when it is no longer needed. 

Моего databaseHelper функции, которые вызываются, когда происходит утечка:

public List<Sticker> getObjectsByGenderAndCategory(String gender, String category) { 
     List<Sticker> objects = new ArrayList<Object>(); 
     String selectQuery = String.format(
       "SELECT * FROM %s WHERE %s = \"%s\" AND %s = \"%s\"", 
       TABLE_OBJECT, KEY_GENDER, gender, KEY_CATEGORY, category); 

     Log.e(LOG, selectQuery); 

     SQLiteDatabase db = this.getReadableDatabase(); 
     Cursor c = db.rawQuery(selectQuery, null); 
    try{ 
     // looping through all rows and adding to list 
     if (c.moveToFirst()) { 
      do { 
       Object o = createClothingItemJavaObject(c); 

       // adding to object list 
       objects.add(o); 
      } while (c.moveToNext()); 
     } 
    }finally { 
      c.close(); 
db.close(); 
    } 
     return objects; 
    } 

я нашел this which I will try tomorrow. It's late.

Спасибо.

+0

Возможный дубликат [SQLite Connection просочился, хотя все закрыто] (http://stackoverflow.com/questions/18147354/sqlite-connection-leaked-although-everything-closed) – sjas

ответ

4

Соответствие каждому звонку getReadableDatabase() и getWritableDatabase() соответствует соответствующему close() на том же объекте базы данных.

Например, ваши getAllClothingItemsByGenderAndCategory() звонки getReadableDatabase(), но не close(). Добавить db.close() после c.close().

Ваш closeDB() не имеет смысла, так как он дает новую ссылку на базу данных с getReadableDatabase() и закрывает только , что. Он ничего не делает, чтобы закрыть существующее соединение с базой данных.

+0

Спасибо. Просто сделал это. Хорошо забудет о моем closeDB(). Что касается моего последнего кода в моем вопросе, я должен также попробовать добавить mDb.close()? – user3164083

+0

Недостаточно контекста, чтобы указать, где было бы целесообразно закрыть помощника. – laalto

+1

Итак, я думаю, это говорит мне, что я не должен просто закрывать его каждый раз, когда я создаю его, когда закончим. Приветствия. В любой ситуации я должен закрыть ее? В некотором контексте: этот блок кода находится в onCreate(), чтобы установить некоторую информацию о том, какой пользователь использует приложение. – user3164083

17

Все, что я сделал, это implement this answer to a similar question, и теперь он не показывает ошибку утечки объекта подключения SQL. Я не могу рекомендовать это достаточно. Для выполнения и работы потребовалось всего несколько минут.

Вот код:

public 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); 
    } 
} 
10

Я установил, добавив

@Override 
protected void finalize() throws Throwable { 
    this.close(); 
    super.finalize(); 
} 

к моему SQLiteOpenHelper расширенного класса

+0

Thanx. Меня устраивает. Он решает мою глобальную проблему db, не приближаясь ко многим запросам, которые я сделал. Не могли бы вы дать какое-то объяснение, что этот код действительно? –

+0

Это работает, спасибо :) – edwardaa

+4

Это заставляет ошибку уйти, скрывая утечку. Это не отличное решение, потому что соединение с базой данных будет закрыто только после сбора мусора - возможно, намного позже, чем вы должны были его закрыть. –

-1

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

+0

@ user6224849 ... измените то, что вы сказали. У этого есть upvote как-то, но это не ясно, потому что ваша фразировка и синтаксис не так хороши. – DSlomer64

Смежные вопросы