philip
philip

Reputation: 1302

How to close a cursor in android

how do you close a cursor this error keeps showing everytime the database is called

10-18 03:29:52.191: E/Cursor(426): Finalizing a Cursor that has not been deactivated or closed. database = /data/data/standard.internet.marketing.mymovingfriend/databases/mymovingfriend, table = movingname, query = SELECT _id, movename, movedate FROM movingname WHERE movename= 'ok'
10-18 03:29:52.191: E/Cursor(426): android.database.sqlite.DatabaseObjectNotClosedException: Application did not close the cursor or database object that was opened here
10-18 03:29:52.191: E/Cursor(426):  at android.database.sqlite.SQLiteCursor.<init>(SQLiteCursor.java:210)
10-18 03:29:52.191: E/Cursor(426):  at android.database.sqlite.SQLiteDirectCursorDriver.query(SQLiteDirectCursorDriver.java:53)
10-18 03:29:52.191: E/Cursor(426):  at android.database.sqlite.SQLiteDatabase.rawQueryWithFactory(SQLiteDatabase.java:1345)
10-18 03:29:52.191: E/Cursor(426):  at android.database.sqlite.SQLiteDatabase.queryWithFactory(SQLiteDatabase.java:1229)
10-18 03:29:52.191: E/Cursor(426):  at android.database.sqlite.SQLiteDatabase.query(SQLiteDatabase.java:1184)
10-18 03:29:52.191: E/Cursor(426):  at android.database.sqlite.SQLiteDatabase.query(SQLiteDatabase.java:1264)
10-18 03:29:52.191: E/Cursor(426):  at standard.internet.marketing.mymovingfriend.SQLHandler.checkMove(SQLHandler.java:1094)
10-18 03:29:52.191: E/Cursor(426):  at standard.internet.marketing.mymovingfriend.ListMovingNames$3.onKey(ListMovingNames.java:98)
10-18 03:29:52.191: E/Cursor(426):  at android.view.View.dispatchKeyEvent(View.java:3735)
10-18 03:29:52.191: E/Cursor(426):  at android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:788)
10-18 03:29:52.191: E/Cursor(426):  at android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:788)
10-18 03:29:52.191: E/Cursor(426):  at android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:788)
10-18 03:29:52.191: E/Cursor(426):  at android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:788)
10-18 03:29:52.191: E/Cursor(426):  at com.android.internal.policy.impl.PhoneWindow$DecorView.superDispatchKeyEvent(PhoneWindow.java:1667)
10-18 03:29:52.191: E/Cursor(426):  at com.android.internal.policy.impl.PhoneWindow.superDispatchKeyEvent(PhoneWindow.java:1102)
10-18 03:29:52.191: E/Cursor(426):  at android.app.Activity.dispatchKeyEvent(Activity.java:2063)
10-18 03:29:52.191: E/Cursor(426):  at com.android.internal.policy.impl.PhoneWindow$DecorView.dispatchKeyEvent(PhoneWindow.java:1643)
10-18 03:29:52.191: E/Cursor(426):  at android.view.ViewRoot.deliverKeyEventToViewHierarchy(ViewRoot.java:2471)
10-18 03:29:52.191: E/Cursor(426):  at android.view.ViewRoot.handleFinishedEvent(ViewRoot.java:2441)
10-18 03:29:52.191: E/Cursor(426):  at android.view.ViewRoot.handleMessage(ViewRoot.java:1735)
10-18 03:29:52.191: E/Cursor(426):  at android.os.Handler.dispatchMessage(Handler.java:99)
10-18 03:29:52.191: E/Cursor(426):  at android.os.Looper.loop(Looper.java:123)
10-18 03:29:52.191: E/Cursor(426):  at android.app.ActivityThread.main(ActivityThread.java:4627)
10-18 03:29:52.191: E/Cursor(426):  at java.lang.reflect.Method.invokeNative(Native Method)
10-18 03:29:52.191: E/Cursor(426):  at java.lang.reflect.Method.invoke(Method.java:521)
10-18 03:29:52.191: E/Cursor(426):  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:868)
10-18 03:29:52.191: E/Cursor(426):  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:626)
10-18 03:29:52.191: E/Cursor(426):  at dalvik.system.NativeStart.main(Native Method)

I tried doing this to close the cursor

public Cursor getMove(){
        String[] columns = new String[]{KEY_ID1, KEY_MOVENAME};
        Cursor cursor = ourDatabase.query(DATABASE_TABLE1, columns, null, null, null, null, null);
        cursor.close();
        return cursor;
    }

now the problem is that it says

10-18 03:47:53.921: E/AndroidRuntime(545): FATAL EXCEPTION: main
10-18 03:47:53.921: E/AndroidRuntime(545): java.lang.RuntimeException: Unable to start activity ComponentInfo{standard.internet.marketing.mymovingfriend/standard.internet.marketing.mymovingfriend.ListMovingNames}: java.lang.IllegalStateException: attempt to re-open an already-closed object: android.database.sqlite.SQLiteQuery (mSql = SELECT _id, movename FROM movingname) 
10-18 03:47:53.921: E/AndroidRuntime(545):  at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2663)
10-18 03:47:53.921: E/AndroidRuntime(545):  at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2679)
10-18 03:47:53.921: E/AndroidRuntime(545):  at android.app.ActivityThread.access$2300(ActivityThread.java:125)
10-18 03:47:53.921: E/AndroidRuntime(545):  at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2033)
10-18 03:47:53.921: E/AndroidRuntime(545):  at android.os.Handler.dispatchMessage(Handler.java:99)
10-18 03:47:53.921: E/AndroidRuntime(545):  at android.os.Looper.loop(Looper.java:123)
10-18 03:47:53.921: E/AndroidRuntime(545):  at android.app.ActivityThread.main(ActivityThread.java:4627)
10-18 03:47:53.921: E/AndroidRuntime(545):  at java.lang.reflect.Method.invokeNative(Native Method)
10-18 03:47:53.921: E/AndroidRuntime(545):  at java.lang.reflect.Method.invoke(Method.java:521)
10-18 03:47:53.921: E/AndroidRuntime(545):  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:868)
10-18 03:47:53.921: E/AndroidRuntime(545):  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:626)
10-18 03:47:53.921: E/AndroidRuntime(545):  at dalvik.system.NativeStart.main(Native Method)
10-18 03:47:53.921: E/AndroidRuntime(545): Caused by: java.lang.IllegalStateException: attempt to re-open an already-closed object: android.database.sqlite.SQLiteQuery (mSql = SELECT _id, movename FROM movingname) 
10-18 03:47:53.921: E/AndroidRuntime(545):  at android.database.sqlite.SQLiteClosable.acquireReference(SQLiteClosable.java:34)
10-18 03:47:53.921: E/AndroidRuntime(545):  at android.database.sqlite.SQLiteQuery.fillWindow(SQLiteQuery.java:64)
10-18 03:47:53.921: E/AndroidRuntime(545):  at android.database.sqlite.SQLiteCursor.fillWindow(SQLiteCursor.java:283)
10-18 03:47:53.921: E/AndroidRuntime(545):  at android.database.sqlite.SQLiteCursor.getCount(SQLiteCursor.java:264)
10-18 03:47:53.921: E/AndroidRuntime(545):  at android.widget.CursorAdapter.getCount(CursorAdapter.java:132)
10-18 03:47:53.921: E/AndroidRuntime(545):  at android.widget.ListView.setAdapter(ListView.java:436)
10-18 03:47:53.921: E/AndroidRuntime(545):  at standard.internet.marketing.mymovingfriend.ListMovingNames.allFunctions(ListMovingNames.java:57)
10-18 03:47:53.921: E/AndroidRuntime(545):  at standard.internet.marketing.mymovingfriend.ListMovingNames.onCreate(ListMovingNames.java:36)
10-18 03:47:53.921: E/AndroidRuntime(545):  at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1047)
10-18 03:47:53.921: E/AndroidRuntime(545):  at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2627)
10-18 03:47:53.921: E/AndroidRuntime(545):  ... 11 more

any solutions?

Upvotes: 2

Views: 562

Answers (2)

philip
philip

Reputation: 1302

This Line of code solves everything

  Cursor c = null;
            try {
                .....
                }
            } finally {
                if(c != null){
                    c.close();
                }       
            }

            return items;
        }

Upvotes: 0

newbyca
newbyca

Reputation: 1513

You have to keep your cursor open until you no longer need data from it. Once you no longer need data from the cursor you just:

cursor.close();

But a much cleaner way to handle data in your Activity is to implement LoaderManager. Do that and you won't have to worry about managing cursor state. Instead Android effectively does it for you.

Upvotes: 3

Related Questions