2009年6月1日 星期一

CursorIndexOutOfBoundsException

今天嘗試自己寫Adapter的時候,在操作Cursor出現了這樣的一個錯誤

android.database.CursorIndexOutOfBoundsException: Index -1 requested, with a size of 1
at android.database.AbstractCursor.checkPosition(AbstractCursor.java:559)
at android.database.AbstractWindowedCursor.checkPosition(AbstractWindowedCursor.java:172)
at android.database.AbstractWindowedCursor.getString(AbstractWindowedCursor.java:41)
at net.poemcode.android.PurseEdit.onCreate(PurseEdit.java:41)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1122)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2104)


CursorIndexOutOfBoundsException,為什麼呢?
看了一下我寫的程式

Cursor c;
.....
int index=0;

for(int i=0;i<c.getColumnCount();i++)
{
if(c.getColumnName(i).equals(NoteDbAdapter.KEY_NOTE))
{
index=i;
}
}

for(int i=0;i<c.getCount();i++)
{
notes.add(c.getString(index));
c.moveToNext();
}

好像也沒什麼錯,查了一下這個例外是由Cursor.getString()丟出來的
查了一下index值也沒錯,getColumnName()等函式也運作正常
後來看了一下源碼,原來是我用SQLite得到的Query結果會存在Cursor這個指標裡
但是這個指標一開始是指向-1的位置
所以源碼裡有一行moveToFirst(),把cursor指到第一個位置,只要把這函式加進去就可以解決了
修改版如下

Cursor c;
.....
int index=0;

for(int i=0;i<c.getColumnCount();i++)
{
if(c.getColumnName(i).equals(NoteDbAdapter.KEY_NOTE))
{
index=i;
}
}
c.moveToFirst();
for(int i=0;i<c.getCount();i++)
{
notes.add(c.getString(index));
c.moveToNext();
}

順便介紹一下Cursor幾個常用的函式

Cursor.getColumnCount()//得到資料表欄位總數
Cursor.getColumnName(int index);//得到資料表第index欄的欄名
Cursor.getColumnIndex(String name)//得到欄名為name的index
Cursor.getCount()//得到傳回資料表的資料筆數
Cursor.getType(int index)
//其中Type可以是String、short等,得到第index欄的資料,,會受到Cursor指標影響

moveToNext()//將Cursor指標移到下一個Row
moveToFirst()//將Cursor指標移到第一個Row
moveToPosition(int index)//將Cursor指標移到第index個Row

沒有留言: