SQLite connection object leaked - Android
Asked Answered
W

4

10

I am making my first android app, and I took some sqlite tutorials first, that taught me to use a databaseHelper that extends SQLiteOpenHelper. So my databaseHelper does extend SQLiteOpenHelper. I get a sqlite connection leak warning in the Logcat so would like some advice about what to do to fix that.

I get this error:

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.

My databaseHelper functions that are called where the leak occurs:

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

I found this which I will try tomorrow. It's late.

Thanks.

Woodie answered 1/2, 2014 at 9:14 Comment(1)
Possible duplicate of SQLite Connection leaked although everything closedActinouranium
W
20

All I did was implement this answer to a similar question and now it doesn't show the SQL connection object leak error. I cannot recommend this enough. It only took a few minutes to implement and worked.

Here is the code:

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);
  }
}
Woodie answered 1/2, 2014 at 23:8 Comment(2)
I'm still get this probelm after use it, but only when edit some strenge condition, that still in misery(idk)..Muth
Could you please help to solve this issueZaragoza
S
14

I fixed this by adding

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

to my SQLiteOpenHelper extended class

Swelter answered 20/5, 2015 at 14:21 Comment(4)
Thanx. It works for me. It solve my global problem of db not getting close from many query i made. Can you please give some explanation what this code do actually?Anhydrite
This makes the error go away by hiding the leak. It isn't a great solution, because the database connection will only be closed after garbage collection - potentially much later than you should have closed it.Pannonia
@DavidSainty i understood that this solved the leakage in a diselegant manner, not that it masked the problem. what do you propose?Whall
@tonygil The finalise only runs some time after the database connection is completely unused AND not correctly close()-d. You would do better to explicitly close() the database connection when you have finished with it, which is what this warning is trying to encourage you to do.Pannonia
B
5

Match each call to getReadableDatabase() and getWritableDatabase() to a corresponding close() on the same database object.

For example, your getAllClothingItemsByGenderAndCategory() calls getReadableDatabase() but does not close() it. Add db.close() after c.close().

Your closeDB() makes no sense since it gets a new reference to the database with getReadableDatabase() and closes just that. It does nothing to close any existing database connection.

Biysk answered 1/2, 2014 at 9:30 Comment(4)
Thanks. Just done that. Ok will forget about my closeDB(). What about my last code block in my question, should I also try adding an mDb.close()?Woodie
There's not enough context to tell where it would be appropriate to close the helper.Biysk
Ok, so I guess that tells me, that I should not just close it everytime I instantiate it when I'm done. Cheers. Any situation I should close it? Some context is: that code block is in an onCreate() to set some information about which user is using the app.Woodie
Could you please help to solve this issueZaragoza
M
-1

Each time you open a database(readable or writable) and cursor which uses memory resources has to be deallocated by using ".close();" after its usage ends in each database function.. by your_database object.close(); and cursor object.close();

Mancunian answered 26/7, 2016 at 4:7 Comment(1)
@user6224849... please alter what you've said. It has an upvote somehow but it's not clear because your phrasing and syntax aren't so good.Spruik

© 2022 - 2024 — McMap. All rights reserved.