How to avoid db not close and cursor exception
Asked Answered
B

2

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

}
}
Bellew answered 2/2, 2011 at 9:18 Comment(0)
W
0

I resolved the exception. I was calling

 db = eventsData.getReadableDatabase();

twice thats why the exception is thrown

Winnow answered 17/2, 2011 at 5:55 Comment(0)
L
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.

Laryngotomy answered 2/2, 2011 at 9:25 Comment(10)
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);Bellew
this is my code protected void onDestroy() { super.onDestroy(); if (cursor!=null){ cursor.close(); } if (db!=null){ db.close(); } }Bellew
im also getting the same exception .. Pls HelpWinnow
Ok, I've updated my answer - have a look at the linked TweetDB class for how I am doing it.Laryngotomy
You close the database after every db-operation? Doing that makes no sense at all.Eccles
@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?Laryngotomy
And opening/closing the DB is not that expensive - there are much longer running things happening.Laryngotomy
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: #4499920Eccles
@warren according to the docs, onTerminate() is not called on real devices. developer.android.com/reference/android/app/… 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.Laryngotomy
@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 showingWinnow
W
0

I resolved the exception. I was calling

 db = eventsData.getReadableDatabase();

twice thats why the exception is thrown

Winnow answered 17/2, 2011 at 5:55 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.