CursorIndexOutOfBounds 异常:请求索引 0,大小为 0

CursorIndexOutOfBounds Exception: Index 0 requested, with a size of 0

我尝试读取 SQLite 数据库列并将每个值存储在一个字符串数组中。我做了以下但它返回异常 cursoroutofbounds。帮我弄清楚我做错了什么?

 public String[] getPlaces(){
   SQLiteDatabase db = this.getReadableDatabase();

    String [] columns = {"place1"};
    c = db.query("rates_table", columns, null, null, null, null, null);
    String[] places = new String[c.getColumnCount()];
    c.moveToNext();

    for(int i=0; i<c.getColumnCount(); i++)
        places[i] = c.getString(i);

    return places;
}

这里:

String[] places = new String[c.getColumnCount()];

c.getColumnCount() 将 return count 行中的列而不是 number of rows in column。使用 c.getCount() 初始化 places 数组:

String[] places = new String[c.getCount()];

或使用ArrayList .

您需要在多个地方更改您的查询和进一步处理。将查询方法的第三个参数改正为适当的 where 子句或将其保留为空。正确循环游标并将其添加到您的字符串中。

public String[] getPlaces(){
    SQLiteDatabase db = this.getReadableDatabase();

    String [] columns = {"place1"};
    c = db.query("rates_table", columns, null, null, null, null, null);


    if (c.getCount() > 0) {   
       String[] places = new String[c.getCount()];
       int i=0;
       c.moveToFirst();
       do {
         places[i] = c.getString(c.getColumnIndex(0))); 
       } while (c.moveToNext());
       return places;
    }
    c.close();
    db.close();


}

我锻炼了一段时间,找到了解决方案:

 public String[] getPlaces(){
        SQLiteDatabase db = this.getReadableDatabase();

        String [] columns = {"place1"};
        c = db.query("rates_table", columns, null, null, null, null, null);

        c.moveToFirst();
        ArrayList<String> places = new ArrayList<String>();
        while(!c.isAfterLast()) {
            places.add(c.getString(c.getColumnIndex("place1")));
            c.moveToNext();
        }
        c.close();
        return places.toArray(new String[places.size()]);

    }

首先你对c = db.query("rates_table", columns, "place1", null, null, null, null);

有疑问

第三个参数将导致没有行被选中。

您可以使用 c = db.query("rates_table", columns, null, null, null, null, null); ,这将 return 所有行。

或者您可以使用 c = db.query("rates_table", columns, "place1 = 'myplace'", null, null, null, null);,在这种情况下,只会显示列 place1 中具有值 myplace 的行。

最佳实践方法是结合使用第 3 个和第 4 个参数,在第 3 个参数中使用 ? 占位符(例如 "place1=?"),并在其中使用相应的参数第 4 个参数(例如 new String[]{"myplace"}),因此要复制之前的查询,您可以使用 c = db.query("rates_table", columns, "place1=?", new String[]{"myplace}, null, null, null);

使用c.moveToNext,将尝试移动到光标的下一行(最初是第一行)。但是,如果它不能移动(即没有行,就像上面描述的那样)它不会失败,而是 returns false(如果光标可以移动则为 true)。

所以你需要检查一下,否则,在没有行的情况下,尝试访问一行将失败,游标越界请求索引 0,大小为 0(即你请求第一个(索引0) 当游标的大小(行数)为0时。

有多种检查方法。

但是我怀疑您会想知道为什么您的循环只显示 1 列。那是因为您在查询中说过只获取 1 列。

如果您将查询的第二个参数更改为空,它将获取所有列。

我猜你想要return一个包含所有地方的数组。

假设这样:-

// get Cursor with all rows(3rd parm null) for the place1 column (2nd parm)
c = db.query("rates_table", columns, null, null, null, null, null);

// Create String array according to the number of rows returned.
String[] places = new String[c.getCount()];

// loop through all rows setting the respective places element with the 
// value obtained from the Cursor
while (c.moveToNext) {
    places[c.getPosition()] = csr.getString(csr.getColumnIndex("place1")); 
}

csr.close(); // Should always close a Cursor
return places;