Praveen Praveen - 4 months ago 21
Android Question

How do I close the Cursor and Database safely?

I've fetched the records from Database using Cursor. It's work perfect. But, I've some errors in Logcat while i'm using this code

public Cursor fetchAll()
{
SQLiteDatabase db = this.getReadableDatabase();
Cursor cursor = db.query(t1, new String[] {"_id",name, date, prior, time, dateformat}, null, null, null, null, prior);
return cursor;
}


My logcat is -

12-16 14:49:20.774: E/Database(18611): close() was never explicitly called on database '/data/data/com.android.application/databases/appZ.db'
12-16 14:49:20.774: E/Database(18611): android.database.sqlite.DatabaseObjectNotClosedException: Application did not close the cursor or database object that was opened here
12-16 14:49:20.774: E/Database(18611): at android.database.sqlite.SQLiteDatabase.<init>(SQLiteDatabase.java:1810)
12-16 14:49:20.774: E/Database(18611): at android.database.sqlite.SQLiteDatabase.openDatabase(SQLiteDatabase.java:817)
12-16 14:49:20.774: E/Database(18611): at android.database.sqlite.SQLiteDatabase.openOrCreateDatabase(SQLiteDatabase.java:851)
12-16 14:49:20.774: E/Database(18611): at android.database.sqlite.SQLiteDatabase.openOrCreateDatabase(SQLiteDatabase.java:844)
12-16 14:49:20.774: E/Database(18611): at android.app.ContextImpl.openOrCreateDatabase(ContextImpl.java:540)
12-16 14:49:20.774: E/Database(18611): at android.content.ContextWrapper.openOrCreateDatabase(ContextWrapper.java:203)
12-16 14:49:20.774: E/Database(18611): at android.database.sqlite.SQLiteOpenHelper.getWritableDatabase(SQLiteOpenHelper.java:98)
12-16 14:49:20.774: E/Database(18611): at android.database.sqlite.SQLiteOpenHelper.getReadableDatabase(SQLiteOpenHelper.java:158)
12-16 14:49:20.774: E/Database(18611): at com.android.todoapplication.DBHelper.fetchAll(DBHelper.java:91)
12-16 14:49:20.774: E/Database(18611): at com.android.todoapplication.ApplicationActivity.sc_adapter(ApplicationActivity.java:1210)
12-16 14:49:20.774: E/Database(18611): at com.android.todoapplication.ApplicationActivity.refresh_data(ApplicationActivity.java:1195)
12-16 14:49:20.774: E/Database(18611): at com.android.todoapplication.ApplicationActivity.onKeyDown(ApplicationActivity.java:1440)
12-16 14:49:20.774: E/Database(18611): at android.view.KeyEvent.dispatch(KeyEvent.java:1037)
12-16 14:49:20.774: E/Database(18611): at android.app.Activity.dispatchKeyEvent(Activity.java:2068)
12-16 14:49:20.774: E/Database(18611): at com.android.internal.policy.impl.PhoneWindow$DecorView.dispatchKeyEvent(PhoneWindow.java:1643)
12-16 14:49:20.774: E/Database(18611): at android.view.ViewRoot.deliverKeyEventToViewHierarchy(ViewRoot.java:2471)
12-16 14:49:20.774: E/Database(18611): at android.view.ViewRoot.handleFinishedEvent(ViewRoot.java:2441)
12-16 14:49:20.774: E/Database(18611): at android.view.ViewRoot.handleMessage(ViewRoot.java:1735)
12-16 14:49:20.774: E/Database(18611): at android.os.Handler.dispatchMessage(Handler.java:99)
12-16 14:49:20.774: E/Database(18611): at android.os.Looper.loop(Looper.java:123)
12-16 14:49:20.774: E/Database(18611): at android.app.ActivityThread.main(ActivityThread.java:4627)
12-16 14:49:20.774: E/Database(18611): at java.lang.reflect.Method.invokeNative(Native Method)
12-16 14:49:20.774: E/Database(18611): at java.lang.reflect.Method.invoke(Method.java:521)
12-16 14:49:20.774: E/Database(18611): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:868)
12-16 14:49:20.774: E/Database(18611): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:626)
12-16 14:49:20.774: E/Database(18611): at dalvik.system.NativeStart.main(Native Method)


I refered something from here. They told that use getReadableDatabase(). I'm using that method also. And, i've also use this method,

public Cursor fetchAll()
{
SQLiteDatabase db = this.getReadableDatabase();
Cursor cursor = db.query(t1, new String[] {"_id",name, date, prior, time, dateformat}, null, null, null, null, prior);
if (cursor!=null)
{
cursor.close();
}
if (db!=null)
{
db.close();
}
return cursor;
}


after that having error like -

Database wasn't open.


After, also i've this errors in my Database. So anyone tell me How do I acquire the safety close for Cursor and Database after fetching the records.

Answer

EDIT: If you return a cursor that is already closed, you can't use it. Open the database before calling the method, then close the cursor and then the database after calling the method.

You can close the cursor after you're done with it like this:

Cursor cursor = fetchAll();
... // Do your work with the cursor
cursor.close();

Or if you're using the cursor from an activity, and need to requery (when the activity is restarted, stopped...) you can use this:

Cursor cursor = fetchAll();
startManagingCursor(cursor); // Android will take care of the cursor for you
// Do your work with the cursor

To close database (after closing the cursor, or if inside an activity in onDestroy() preferably):

dbhelper.close();
Comments