2

Possible Duplicate:
Android error - close() was never explicitly called on database

I have a problem in my android app.

I have a singleton implemented which has a method with the following code:

public Cursor getFooCursor(Context context)
{
    StorageDBOpenHelper helper = new StorageDBOpenHelper(context);
    SQLiteDatabase db = helper.getReadableDatabase();

    Cursor c = db.query("Foo", new String[] {"_id", "Titel"}, null, null, null, null, "Test DESC");

    return c;
}

when i use this, i sometimes get the error: SQLiteDatabase: close() was never explicitly called on database

how to avoid this? the problem is, i can not simply make a db.close() befor i return c, because then its empty.

Community
  • 1
  • 1
gurehbgui
  • 14,236
  • 32
  • 106
  • 178

2 Answers2

2

Clients should open the database, then use this method to fetch the cursor, then close both the cursor and the database when they are finished. I would recommend not using a singleton here. Instead do something like this:

public class FooDB
{
    private SQLiteDatabase db = null;

    private void open() throws SQLiteException
    {
        if (db != null)
        {
            throw new SQLiteException("Database already opened");
        }

        // Create our open helper
        StorageDBOpenHelper helper = new StorageDBOpenHelper(context);
        try
        {
            // Try to actually get the database objects
            db = m_openHelper.getWritableDatabase();
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }

        if (db == null)
        {
            throw new SQLiteException("Failed to open database");
        }
    }

    private void close() throws SQLiteException
    {
        if (db != null)
        {
            db.close();
            db = null;
        }        
    }

    public Cursor getFooCursor(Context context)
    {
        if(db == null)
            throw new SQLiteException("Database not open");    

        Cursor c = db.query("Foo", new String[] {"_id", "Titel"}, null, null, null, null, "Test DESC");

        return c;
    }
}
Samuel
  • 16,923
  • 6
  • 62
  • 75
2

The approach I use is to pass an instance of the db to a class that returns the cursor:

StorageDBOpenHelper helper = new StorageDBOpenHelper(context);
SQLiteDatabase db = helper.getReadableDatabase();

public Cursor getFooCursor(Context context, SQLiteDatabase db ) {
      Cursor c = db.query("Foo", new String[] {"_id", "Titel"}, null, null, null,
 null, "Test DESC");
      return c;
 }

db.close();
Mohamed_AbdAllah
  • 5,311
  • 3
  • 28
  • 47