web-dev-qa-db-ja.com

android.database.CursorIndexOutOfBoundsException

私のAndroidアプリのデータアクセスコードは、例外を発生させます。

例外の原因となるコードは次のとおりです。

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);
    ....
}

発生する例外は次のとおりです。

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

Logメソッドは結果を生成します2 post rows

ここで何が問題になっていますか?

編集:私は完全なスタックトレースを追加したので、それを表示したい人はそうすることができます。

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
8
Sandah Aung

インデックス2のアイテムを取得しようとしていますが、このインデックスは実際には存在しません(カーソルサイズが2であるため、インデックスは0,1です)。

ループを変更します。

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

これで正しく動作するはずです。

注:カーソルを最初のレコードに移動し(暗黙的に最初の行の前に配置されます)、読み取りの準備をするmoveToFirst()メソッドを呼び出すことを忘れないでください。これは、カーソルが有効かどうかをテストするための便利な方法でもあります。

注2:列インデックスは使用しないでください。カウントを間違える可能性があります。列名を使用する代わりに、このアプローチは一般的に推奨されます。 cursor.getColumnIndex("<columnName>")

36
Simon Dorociak

カーソルインデックスを最初に移動していません..以下のようにしてみてください

 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();
6
CRUSADER

これは、Cursorにデータがあるが、データリストの最初のインデックスをまだ指していない場合に発生します。

この例外を回避するには、最初に以下を確認する必要があります。

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

そして、さらなる行動を実行します。

5
sud007