0

Like the title says, I have a listview populated with a cursoradapter. I can scroll the list just fine for the first 50 elements let's say, however it crashes if I try to scroll further, and it crashes always at the same point. I include the stack trace, it hasn't been very useful to me though: all the calls are made inside the android framework, so even though I know that the problem is a closed db at the end, I don't know which part of my code is the problem. Inside the same app I have other listviews based on cursors which do not pose any problem. I don't have any other ideas of the cause.

java.lang.IllegalStateException: The database '/storage/emulated/0/***/db/***.sqlite' is not open.
        at android.database.sqlite.SQLiteDatabase.throwIfNotOpenLocked(SQLiteDatabase.java:2169)
        at android.database.sqlite.SQLiteDatabase.createSession(SQLiteDatabase.java:365)
        at android.database.sqlite.SQLiteDatabase$1.initialValue(SQLiteDatabase.java:84)
        at android.database.sqlite.SQLiteDatabase$1.initialValue(SQLiteDatabase.java:81)
        at java.lang.ThreadLocal$Values.getAfterMiss(ThreadLocal.java:430)
        at java.lang.ThreadLocal.get(ThreadLocal.java:65)
        at android.database.sqlite.SQLiteDatabase.getThreadSession(SQLiteDatabase.java:359)
        at android.database.sqlite.SQLiteProgram.getSession(SQLiteProgram.java:101)
        at android.database.sqlite.SQLiteQuery.fillWindow(SQLiteQuery.java:62)
        at android.database.sqlite.SQLiteCursor.fillWindow(SQLiteCursor.java:152)
        at android.database.sqlite.SQLiteCursor.onMove(SQLiteCursor.java:124)
        at android.database.AbstractCursor.moveToPosition(AbstractCursor.java:214)
        at android.database.CursorWrapper.moveToPosition(CursorWrapper.java:162)
        at android.widget.CursorAdapter.getItemId(CursorAdapter.java:223)
        at android.widget.AbsListView$RecycleBin.retrieveFromScrap(AbsListView.java:6753)
        at android.widget.AbsListView$RecycleBin.getScrapView(AbsListView.java:6492)
        at android.widget.AbsListView.obtainView(AbsListView.java:2343)
        at android.widget.ListView.makeAndAddView(ListView.java:1864)
        at android.widget.ListView.fillDown(ListView.java:698)
        at android.widget.ListView.fillGap(ListView.java:662)
        at android.widget.AbsListView.trackMotionScroll(AbsListView.java:4968)
        at android.widget.AbsListView$FlingRunnable.run(AbsListView.java:4512)
        at android.view.Choreographer$CallbackRecord.run(Choreographer.java:767)
        at android.view.Choreographer.doCallbacks(Choreographer.java:580)
        at android.view.Choreographer.doFrame(Choreographer.java:549)
        at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:753)
        at android.os.Handler.handleCallback(Handler.java:739)
        at android.os.Handler.dispatchMessage(Handler.java:95)
        at android.os.Looper.loop(Looper.java:135)
        at android.app.ActivityThread.main(ActivityThread.java:5221)
        at java.lang.reflect.Method.invoke(Native Method)
        at java.lang.reflect.Method.invoke(Method.java:372)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:899)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:694)
flower_green
  • 1,314
  • 2
  • 25
  • 30
  • the log says your db is closed, did you call close() method? – pskink May 09 '15 at 17:55
  • Not on purpose. The cursor is returned from a call to a content provider. The content provider retrieves the cursor with a rawQuery to the db. The db is closed after the cursor is retrieved. However I do the same thing for other listview and it does not give any problem. – flower_green May 09 '15 at 19:08
  • 1
    its because other Cursors were smaller and they fit into one buffer called CursorWindow – pskink May 09 '15 at 19:15
  • Thank you very much, indeed removing the call to close in the contentprovider solved the issue. However I now have to refactor the code and find when to close the db. Do you have any source for this kind of pattern, or about this cursor window thingt? (ie, closing the db with a cursor adapter) Or is it better to load the whole db in models and use a baseadapter? I'm afraid it will take too much memory though. Also, if you make an answer I will mark it as accepted (even just for the close() removing advice) – flower_green May 10 '15 at 11:33
  • Found the problem: http://stackoverflow.com/questions/4547461/closing-the-database-in-a-contentprovider?lq=1 Appearantly, there's no need to call close in a content provider, however the documentation is a bit lacking in this sense. – flower_green May 10 '15 at 12:06

1 Answers1

3

you have closed your db and SQLiteCursor needs to fill its window while scrolling the ListView, see here https://groups.google.com/forum/#!msg/android-developers/NwDRpHUXt0U/jIam4Q8-cqQJ on when you should close your db, the answer is: there is no need of doing that

pskink
  • 23,874
  • 6
  • 66
  • 77