11

The data access code in my Android app raises an exception.

Here is the code that causes the exception:

String getPost = "SELECT * FROM " + TABLE_POST + ";";
Cursor result = getReadableDatabase().rawQuery(getPost, null);
List posts = new ArrayList();{
Log.d("count", result.getCount() + " post rows");
while (result != null && result.moveToNext());
    Post post = new Post();
    post.setPostId(result.getInt(0));
    posts.add(post);
    ....
}

The exception raised is:

android.database.CursorIndexOutOfBoundsException: Index 2 requested, with a size of 2 exception

The log method produces the result 2 post rows.

What is wrong here?

Edit: I have added the full stack trace so that those wishing to view it can do so.

11-14 09:57:50.538: W/dalvikvm(4710): threadid=1: thread exiting with uncaught exception (group=0x40a71930)
11-14 09:57:50.608: E/AndroidRuntime(4710): FATAL EXCEPTION: main
11-14 09:57:50.608: E/AndroidRuntime(4710): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.innolabmm.software.collaboration/com.innolabmm.software.collaboration.PostCommentActivity}: android.database.CursorIndexOutOfBoundsException: Index 2 requested, with a size of 2
11-14 09:57:50.608: E/AndroidRuntime(4710):     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2180)
11-14 09:57:50.608: E/AndroidRuntime(4710):     at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2230)
11-14 09:57:50.608: E/AndroidRuntime(4710):     at android.app.ActivityThread.access$600(ActivityThread.java:141)
11-14 09:57:50.608: E/AndroidRuntime(4710):     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1234)
11-14 09:57:50.608: E/AndroidRuntime(4710):     at android.os.Handler.dispatchMessage(Handler.java:99)
11-14 09:57:50.608: E/AndroidRuntime(4710):     at android.os.Looper.loop(Looper.java:137)
11-14 09:57:50.608: E/AndroidRuntime(4710):     at android.app.ActivityThread.main(ActivityThread.java:5041)
11-14 09:57:50.608: E/AndroidRuntime(4710):     at java.lang.reflect.Method.invokeNative(Native Method)
11-14 09:57:50.608: E/AndroidRuntime(4710):     at java.lang.reflect.Method.invoke(Method.java:511)
11-14 09:57:50.608: E/AndroidRuntime(4710):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:793)
11-14 09:57:50.608: E/AndroidRuntime(4710):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:560)
11-14 09:57:50.608: E/AndroidRuntime(4710):     at dalvik.system.NativeStart.main(Native Method)
11-14 09:57:50.608: E/AndroidRuntime(4710): Caused by: android.database.CursorIndexOutOfBoundsException: Index 2 requested, with a size of 2
11-14 09:57:50.608: E/AndroidRuntime(4710):     at android.database.AbstractCursor.checkPosition(AbstractCursor.java:424)
11-14 09:57:50.608: E/AndroidRuntime(4710):     at android.database.AbstractWindowedCursor.checkPosition(AbstractWindowedCursor.java:136)
11-14 09:57:50.608: E/AndroidRuntime(4710):     at android.database.AbstractWindowedCursor.getInt(AbstractWindowedCursor.java:68)
11-14 09:57:50.608: E/AndroidRuntime(4710):     at com.innolabmm.software.collaboration.data.CollaborationDbHandler.fetchAllPost(CollaborationDbHandler.java:362)
11-14 09:57:50.608: E/AndroidRuntime(4710):     at com.innolabmm.software.collaboration.PostCommentActivity.onCreate(PostCommentActivity.java:48)
11-14 09:57:50.608: E/AndroidRuntime(4710):     at android.app.Activity.performCreate(Activity.java:5104)
11-14 09:57:50.608: E/AndroidRuntime(4710):     at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1080)
11-14 09:57:50.608: E/AndroidRuntime(4710):     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2144)
11-14 09:57:50.608: E/AndroidRuntime(4710):     ... 11 more
Sandah Aung
  • 6,156
  • 15
  • 56
  • 98

3 Answers3

43

You are attempting to retrieve an item on index 2 but this index really doesn't exist (Cursor size is 2 so indexes are 0,1).

Change your loop:

if (result != null && result.moveToFirst()){
    do {
       Post post = new Post();
       post.setPostId(result.getInt(0));
       posts.add(post);
       ....
    } while (result.moveToNext());
}

Now it should work correctly.

Note: Don't forget to call moveToFirst() method that moves Cursor into the first record (implicitly is positioned before the first row) and prepares it for reading. This is also a handy method for testing whether Cursor is valid or not.

Note 2: Don't use column indexes, you can simply make a mistake in counting. Instead of use column names - this approach is generally recommended e.q. cursor.getColumnIndex("<columnName>")

Simon Dorociak
  • 33,374
  • 10
  • 68
  • 106
7

You havent moved cursor index to first .. Try like this below

 String getPost = "SELECT * FROM " + TABLE_POST + ";";
    Cursor result = getReadableDatabase().rawQuery(getPost, null);
    List posts = new ArrayList();{
    Log.d("count", result.getCount() + " post rows");

    if (result .moveToFirst()) {
        do {
             Post post = new Post();
             post.setPostId(result.getInt(0));
             posts.add(post);
              ....
        } while (result .moveToNext());
    }
    result .close();
CRUSADER
  • 5,486
  • 3
  • 28
  • 64
3

This arises in the case our Cursor has data but not yet pointing to first index in the data list.

To get avoid this exception, we first should check:

if (!cursor.moveToFirst())
        cursor.moveToFirst();

And then carry the further actions.

sud007
  • 5,824
  • 4
  • 56
  • 63
  • 2
    Maybe I'm missing something, but why call cursor.moveToFirst() twice? – Brill Pappin May 22 '18 at 19:40
  • @BrillPappin You are calling that only once. `if (!cursor.moveToFirst())` just checks if it has moved or not. And `cursor.moveToFirst();` is only called if it did not move to first. – sud007 May 23 '18 at 07:00
  • 2
    no, you are actually calling it twice. The work done to give you the result is the same. So cursor.moveToFirst() does not change its functionality when inside the IF condition. You don't need the second call, because the first call in the IF block will do all you need (obviously, don't invert the result). – Brill Pappin May 24 '18 at 16:10
  • Try it yourself, write a unit test, and try it both ways. – Brill Pappin May 24 '18 at 16:11