2
02-02 14:31:34.048: WARN/SQLiteCompiledSql(359): Releasing statement in a finalizer. Please ensure that you explicitly call close() on your cursor: SELECT * FROM 
02-02 14:31:34.048: WARN/SQLiteCompiledSql(359): android.database.sqlite.DatabaseObjectNotClosedException: Application did not close the cursor or database object that was opened here
02-02 14:31:34.129: ERROR/Database(359): android.database.sqlite.DatabaseObjectNotClosedException: Application did not close the cursor or database object that was opened here
02-02 14:31:34.129: ERROR/Database(359):     at 

How to avoid this exception ?? Pls help

My code is given below :

 **DataSQLHelper .class**

public class DataSQLHelper extends SQLiteOpenHelper {
private static final String DATABASE_NAME = "test.db";
private static final int DATABASE_VERSION = 1;

   public DataSQLHelper (Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}



@Override
public void onCreate(SQLiteDatabase db) {
    String sql = "create table " + TABLE + "( " + BaseColumns._ID
    + " integer primary key autoincrement, " + ID + " text, "
    + PASSWORD + " text, " + ACTIVE + " text, " + STATUS
    + " text);";
    db.execSQL(sql);

}

@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
if (oldVersion >= newVersion)
    return;

String sql = null;
if (oldVersion == 1)
    sql = "alter table " + TABLE + " add note text;";
if (oldVersion == 2)
    sql = "";


if (sql != null)
    db.execSQL(sql);
}

        @Override
    public synchronized void close() {
                   super.close();


    }

}


    ***Test_Java .java***

     public class Test_Java extends Activity {
  DataSQLHelper helData;
SQLiteDatabase db;
Cursor cursor;


@Override
public void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);
    setContentView(R.layout.main);

    try {      

        helData= new DataSQLHelper(this);
     cursor = getData();
    startManagingCursor(cursor);

    setContentView(R.layout.view);


} catch (Exception ex) {

    }

    } // onCreate Ends



private Cursor getData() {
try {
     db = helData.getReadableDatabase();
     cursor = db.query(DataSQLHelper.TABLE, null, null,
        null, null, null, null);
    startManagingCursor(cursor);
    return cursor;
} catch (Exception ex) {
    System.out.println("Exception Occured : " + ex.toString());
    return null;
}

}

@Override
protected void onDestroy() {
   System.out.println("onDestroy");
    super.onDestroy();
    if (db!=null){
                   db.close();
                }
    if (cursor!=null){
                    cursor.close();
    }

    if ( helData!=null){
        helData.close();
    }

}
}
WarrenFaith
  • 57,492
  • 25
  • 134
  • 150
MorningGlory
  • 758
  • 1
  • 11
  • 21

2 Answers2

4

You should reverse the close statements within your onDestroy() method. First close the cursor, then the db:

if (cursor!=null){
    cursor.close();
}
if (db!=null){
    db.close();
}

You basically need to reverse the order of creating/opening db and cursor.

Also note that the db/cursor in the example is opened in onCreate() which is a callback from the system. You may want to close the cursor/db before leaving that method. You are free to cache the DataSQLHelper in your application.

In my application Zwitscher, I have put the whole db/cursor handling with the methods of the SQLHelper class so that the layers above do not have to care about it. See its TweetDB class.

Heiko Rupp
  • 30,426
  • 13
  • 82
  • 119
  • i have given like this Heiko.. but still getting the same exception .. and the line is inside the method getData() ; db = helData.getReadableDatabase(); & cursor = db.query(DataSQLHelper.TABLE, null, null, null, null, null, null); – MorningGlory Feb 02 '11 at 09:39
  • this is my code protected void onDestroy() { super.onDestroy(); if (cursor!=null){ cursor.close(); } if (db!=null){ db.close(); } } – MorningGlory Feb 02 '11 at 09:39
  • im also getting the same exception .. Pls Help – jennifer Feb 02 '11 at 09:49
  • Ok, I've updated my answer - have a look at the linked TweetDB class for how I am doing it. – Heiko Rupp Feb 02 '11 at 09:59
  • 4
    You close the database after every db-operation? Doing that makes no sense at all. – WarrenFaith Feb 02 '11 at 10:13
  • @Warren How would you do it - given the fact that an application can be paused at any time and that there are multiple path back into the application? – Heiko Rupp Feb 02 '11 at 12:12
  • And opening/closing the DB is not that expensive - there are much longer running things happening. – Heiko Rupp Feb 02 '11 at 12:13
  • 1
    I would extend the application class, open the database there in `onCreate` and close it in `onTerminate`. Keeping the instance of the database in the application enable you to access the database from everywhere at any time. "is not that expensive" doesn't mean it is cheap. A short sample can be found here: http://stackoverflow.com/questions/4499420/how-can-i-clear-a-sqlite-database-each-time-i-start-my-app/4499476#4499476 – WarrenFaith Feb 02 '11 at 12:28
  • @warren according to the docs, onTerminate() is not called on real devices. http://developer.android.com/reference/android/app/Application.html#onTerminate() This actually worries me, as if a writable DB is not closed, there is no guarantee that all data is written. Especially as an app to terminate is just killed away. – Heiko Rupp Feb 02 '11 at 21:17
  • @Heiko Rupp I have given @Override protected void onDestroy() { close(); if (db!=null){ db.close(); } super.onDestroy(); } public void close() { eventsData.close(); } ..But still the exception is showing – jennifer Feb 14 '11 at 09:16
0

I resolved the exception. I was calling

 db = eventsData.getReadableDatabase();

twice thats why the exception is thrown

jennifer
  • 8,133
  • 22
  • 69
  • 96