當前位置: 首頁>>技術問答>>正文


android.database.CursorIndexOutOfBoundsException:請求索引0,大小為0

安卓數據庫問題描述

我正在使用擴展自遊標適配器(curosr adapter)的自定義適配器,在列表視圖(listview)中顯示數據,實際顯示的數據是特定的電話號碼。我已經把id傳遞給了數據庫類中的方法,但係統報錯:

errorandroid.database.CursorIndexOutOfBoundsException: Index 0 requested, with a size of 0 

如果在方法中設置調試器(debugger),但是不會運行到這一行之後:

num = cursor.getString(cursor.getColumnIndex("ContactNumber"));

這是主要相關代碼:

public String getNumberFromId(int id) 
{
    String num;
    db= this.getReadableDatabase();
    Cursor cursor = db.query(scheduletable, new String[] { "ContactNumber" },"_id="+id, null, null, null, null);
    cursor.moveToFirst();
    num = cursor.getString(cursor.getColumnIndex("ContactNumber")); 
    cursor.close();
    db.close();
    return num;
}

這個問題到底要怎麽解決呢?

推薦的解決方法

每當您要處理遊標時,始終都必須檢查cursor為是否null,並且要檢查moveToFirst()是否執行成功。如下麵的代碼所示:

if( cursor != null && cursor.moveToFirst() ){
    num = cursor.getString(cursor.getColumnIndex("ContactNumber"));
    cursor.close(); 
}

可以適當地打印日誌查看是否返回null或空的遊標。根據日誌情況,如果發現有問題,再檢查下cursor查詢操作是否正確。

注意1:考慮到“C1 && C2”符號執行時,前麵的條件C1返回True才會執行後麵的條件C2,所以把 cursor != null && cursor.moveToFirst()寫在一起更簡潔高效

注意2:遊標的close()調用也應該在cursor有效時才能執行。

次佳解決辦法

在獲取數據之前需要先對cursor檢查如下的條件:

if(cursor!=null && cursor.getCount()>0){
  cursor.moveToFirst();
  num = cursor.getString(cursor.getColumnIndex("ContactNumber")); 
}

第三種解決思路

在您嘗試從遊標讀取任何數據之前,請先檢查遊標moveToFirst()的返回值。題主的問題看起來是因為好像沒有返回任何結果。

正確的示例代碼

Cursor查詢和保存的示例代碼

// just one,單列
Cursor cursor = db.query(...);
if (cursor != null) {
    if (cursor.moveToFirst()) {
        value = cursor.getSomething();
    }
    cursor.close();
}

// multiple columns, 多列的情形
Cursor cursor = db.query(...);
if (cursor != null) {
    while (cursor.moveToNext()) {
        values.add(cursor.getSomething());
    }
    cursor.close();
}

數據庫遊標執行moveToNext()示意圖:
database_cursor

參考資料

本文由《純淨天空》出品。文章地址: https://vimsky.com/zh-tw/article/3593.html,未經允許,請勿轉載。