My Google Play dev console has reported its first crash to me for my Android app. It looks like SQLite was unable to allocate memory to the cursor, but I've never seen this before and can't reproduce it. Any ideas?
Stackgrace reported by Google:
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.NsouthProductions.gradetrackerpro/com.NsouthProductions.gradetrackerpro.Activity_Category}: android.database.CursorWindowAllocationException: Cursor window allocation of 2048 kb failed. # Open Cursors=530 (# cursors opened by this proc=530)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2305)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2363)
at android.app.ActivityThread.access$900(ActivityThread.java:161)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1265)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:157)
at android.app.ActivityThread.main(ActivityThread.java:5356)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1265)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1081)
at dalvik.system.NativeStart.main(Native Method)
Caused by: android.database.CursorWindowAllocationException: Cursor window allocation of 2048 kb failed. # Open Cursors=530 (# cursors opened by this proc=530)
at android.database.CursorWindow.<init>(CursorWindow.java:108)
at android.database.CursorWindow.<init>(CursorWindow.java:100)
at android.database.AbstractWindowedCursor.clearOrCreateWindow(AbstractWindowedCursor.java:198)
at android.database.sqlite.SQLiteCursor.clearOrCreateWindow(SQLiteCursor.java:301)
at android.database.sqlite.SQLiteCursor.fillWindow(SQLiteCursor.java:139)
at android.database.sqlite.SQLiteCursor.getCount(SQLiteCursor.java:133)
at android.database.AbstractCursor.moveToPosition(AbstractCursor.java:197)
at android.database.AbstractCursor.moveToFirst(AbstractCursor.java:237)
at com.NsouthProductions.gradetrackerpro.DBAdapter.getCourse(DBAdapter.java:401)
at com.NsouthProductions.gradetrackerpro.Activity_Category$CategoryActivityFragment.setListData(Activity_Category.java:196)
at com.NsouthProductions.gradetrackerpro.Activity_Category$CategoryActivityFragment.onCreateView(Activity_Category.java:182)
at android.support.v4.app.Fragment.performCreateView(Fragment.java:1500)
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:938)
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1115)
at android.support.v4.app.BackStackRecord.run(BackStackRecord.java:682)
at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1478)
at android.support.v4.app.FragmentActivity.onStart(FragmentActivity.java:570)
at android.app.Instrumentation.callActivityOnStart(Instrumentation.java:1189)
at android.app.Activity.performStart(Activity.java:5436)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2278)
... 11 more
Where it failed in my DBAdapter class.
public Course getCourse (int rowId) throws SQLException {
Cursor c =
db.query(true, TABLE_COURSES, new String[] {KEY_ID, KEY_TITLE,
KEY_YEAR, KEY_SEASON, KEY_CREDIT}, KEY_ID + "=" + rowId, null, null, null, null, null);
if (c != null) {
c.moveToFirst();
}
Course course = new Course(c.getInt(0), c.getString(1), c.getInt(2), c.getString(3), c.getDouble(4));
return course;
}
Where the DBAdapter function is called. At this point in the activity, the db has already been opened, queried, and closed successfully.
public void setListData(){
db.open();
Grade[] g = db.getGradesInCategory(catId);
this.getActivity().setTitle(db.getCourse(courseId).getTitle());
db.close();
That is an OutOfMemoryError
, in effect. Quoting the comments for that exception class:
This exception is thrown when a CursorWindow couldn't be allocated, most probably due to memory not being available.
The error message shows that you have 530 open Cursor
objects, which may be part of your problem. For example, you are leaking a Cursor
in your getCourse()
method. Make sure that you close your Cursor
as soon as you are done with it.
If that does not help, you will need to treat this like an OutOfMemoryError
and determine where else you are wasting heap space, perhaps by using tools like MAT.
Cursors need to be closed:
Cursor c = db.query(...);
try {
...
} finally {
c.close();
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With