2 annbnncnnd AnnBnnCnnD 于 2013.01.05 15:19 提问

为什么会得到CursorIndexOutOfBoundsException?

我把全部代码都贴上,cursor好像不对。

package com.tanukiproductions.battleforchristmas;

import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;

public class SQLiteTable {

public static final String KEY_ROWID = "_id";
public static final String KEY_LEVEL = "level";
public static final String KEY_HEALTH = "health";
public static final String KEY_NAME = "name";
public static final String KEY_CRIT = "crit";
public static final String KEY_CRIT_RANGE = "crit_range";
public static final String KEY_CRIT_INC = "crit_increment";
public static final String KEY_HIT_RANGE = "hit_range";
public static final String KEY_HIT_INC = "hit_increment";
public static final String KEY_CHAR_IMG = "character_image";
public static final String KEY_TOTAL_XP = "total_xp";
public static final String KEY_XP = "xp";
public static final String KEY_XP_NEEDED = "xp_needed";
public static final String KEY_COINS = "coins";
public static final String KEY_SMALL_POTS = "small_pots";
public static final String KEY_LARGE_POTS = "large_pots";

private static DbHelper ourHelper;
private final Context ourContext;
private static SQLiteDatabase ourDatabase;

private static final String DB_NAME = "battle_for_christams";
private static final String DB_TBL = "stats";
private static final int DATABASE_VERSION = 1;

private static class DbHelper extends SQLiteOpenHelper{

    public DbHelper(Context context) {
        super(context, DB_NAME, null, DATABASE_VERSION);
        // TODO Auto-generated constructor stub
    }
    @Override
    public void onCreate(SQLiteDatabase db) {
        // TODO Auto-generated method stub
        db.execSQL("CREATE TABLE " + DB_TBL + " (" +
                KEY_ROWID + " INTEGER PRIMARY KEY AUTOINCREMENT, " + 
                KEY_LEVEL + " INTEGER NOT NULL, " + 
                KEY_HEALTH + " INTEGER NOT NULL, " +
                KEY_NAME + " TEXT NOT NULL, " +
                KEY_CRIT + " INTEGER NOT NULL, " +
                KEY_CRIT_RANGE + " INTEGER NOT NULL, " +
                KEY_CRIT_INC + " INTEGER NOT NULL, " +
                KEY_HIT_RANGE + " INTEGER NOT NULL, " +
                KEY_HIT_INC + " INTEGER NOT NULL, " +
                KEY_CHAR_IMG + " INTEGER NOT NULL, " +
                KEY_TOTAL_XP + " INTEGER NOT NULL, " +
                KEY_XP + " INTEGER NOT NULL, " +
                KEY_XP_NEEDED + " INTEGER NOT NULL, " +
                KEY_COINS + " INTEGER NOT NULL, " + 
                KEY_SMALL_POTS + " INTEGER NOT NULL, " +
                KEY_LARGE_POTS + " INTEGER NOT NULL)"
            );

        ContentValues values = new ContentValues();
        values.put(KEY_NAME, "User1");
        values.put( KEY_LEVEL, 1);
        values.put(KEY_HEALTH, 10);
        values.put(KEY_CRIT, 5);
        values.put(KEY_CRIT_RANGE, 2);
        values.put(KEY_CRIT_INC, 2);
        values.put(KEY_HIT_RANGE, 2);
        values.put(KEY_HIT_INC, 0);
        values.put(KEY_TOTAL_XP, 0);
        values.put(KEY_XP, 0);
        values.put(KEY_XP_NEEDED, 5);
        values.put(KEY_COINS, 5);
        values.put(KEY_SMALL_POTS, 0);
        values.put(KEY_LARGE_POTS, 0);
        values.put(KEY_CHAR_IMG, 1);
        db.insert(DB_TBL,  null, values);

    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        // TODO Auto-generated method stub
        db.execSQL("DROP TABLE IF EXIST " + DB_TBL);
        onCreate(db);
    }

}

public SQLiteTable(Context c){
    ourContext = c;
    ourHelper = new DbHelper(ourContext);
}

public static void open() throws SQLException{
    ourDatabase = ourHelper.getWritableDatabase();
}

public static void close() throws SQLException{
    ourHelper.close();
}

public int getLevel() {
    open();
    Cursor cursor = ourDatabase.query(DB_TBL, new String[] {KEY_LEVEL}, null, null, null, null, null);
    int level = cursor.getInt(0);
    cursor.close();
    close();
    return level;
}

public int getHealth() {
    open();
    Cursor cursor = ourDatabase.query(DB_TBL, new String[] {KEY_HEALTH}, null, null, null, null, null);
    int health = cursor.getInt(0);
    cursor.close();
    close();
    return health;
}

public int getCrit() {
    // TODO Auto-generated method stub
    open();
    Cursor cursor = ourDatabase.query(DB_TBL, new String[] {KEY_CRIT}, null, null, null, null, null);
    int crit = cursor.getInt(0);
    cursor.close();
    close();
    return crit;
}

public int getCritRange() {
    // TODO Auto-generated method stub
    open();
    Cursor cursor = ourDatabase.query(DB_TBL, new String[] {KEY_CRIT_RANGE}, null, null, null, null, null);
    int critRange = cursor.getInt(0);
    cursor.close();
    close();
    return critRange;
}

public int getCritInc() {
    // TODO Auto-generated method stub
    open();
    Cursor cursor = ourDatabase.query(DB_TBL, new String[] {KEY_CRIT_INC}, null, null, null, null, null);
    int critInc = cursor.getInt(0);
    cursor.close();
    close();
    return critInc;
}

public int getHitInc() {
    // TODO Auto-generated method stub
    open();
    Cursor cursor = ourDatabase.query(DB_TBL, new String[] {KEY_HIT_INC}, null, null, null, null, null);
    int hitInc = cursor.getInt(0);
    cursor.close();
    close();
    return hitInc;
}

public int getHitRange() {
    // TODO Auto-generated method stub
    open();
    Cursor cursor = ourDatabase.query(DB_TBL, new String[] {KEY_HIT_RANGE}, null, null, null, null, null);
    int hitRange = cursor.getInt(0);
    cursor.close();
    close();
    return hitRange;
}

public int getXp() {
    open();
    Cursor cursor = ourDatabase.query(DB_TBL, new String[] {KEY_XP}, null, null, null, null, null);
    int xp = cursor.getInt(0);
    cursor.close();
    close();
    return xp;
}

public void setXp(int xp){
    open();
    ContentValues values = new ContentValues();
    int xpNeeded = getXpNeeded();
    int XP = getXp() + xp;
    int totalXp = getTotalXp() + xp;
    if ( XP >= xpNeeded ){
        XP = XP - xpNeeded;
        levelUp();
    }
    values.put(KEY_XP, XP);
    values.put(KEY_TOTAL_XP, totalXp);
    ourDatabase.update(DB_TBL, values, null, null);
    close();

}

public int getXpNeeded() {
    open();
    Cursor cursor = ourDatabase.query(DB_TBL, new String[] {KEY_XP_NEEDED}, null, null, null, null, null);
    int xpNeeded = cursor.getInt(0);
    cursor.close();
    close();
    return xpNeeded;
}

public int getTotalXp() {
    open();
    Cursor cursor = ourDatabase.query(DB_TBL, new String[] {KEY_TOTAL_XP}, null, null, null, null, null);
    int totalXp = cursor.getInt(0);
    cursor.close();
    close();
    return totalXp;
}

public int getCoins() {
    open();
    Cursor cursor = ourDatabase.query(DB_TBL, new String[] {KEY_COINS}, null, null, null, null, null);
    int coins = cursor.getInt(0);
    cursor.close();
    close();
    return coins;
}

public String getName() {
    // TODO Auto-generated method stub
    open();
    Cursor cursor = ourDatabase.query(DB_TBL, new String[] {KEY_NAME}, null, null, null, null, null);
    String name = cursor.getString(0);
    cursor.close();
    close();
    return name;
}

public void levelUp() {
    // TODO Auto-generated method stub
    ContentValues values = new ContentValues();
    int level = getLevel() + 1;
    int health = getHealth() + 5;
    double crit = getCrit() + 0.1;
    int xpNeeded = getXpNeeded() + 5;
    int critInc = getCritInc() + 1;
    int hitInc;
    int hitRange;
    int critRange;
    values.put(KEY_LEVEL, level);
    values.put(KEY_HEALTH, health);
    values.put(KEY_CRIT, crit);
    values.put(KEY_XP_NEEDED, xpNeeded);
    values.put(KEY_CRIT_INC, critInc);
    if(level % 2 == 0){
        hitInc = getHitInc() + 1;
        values.put(KEY_HIT_INC, hitInc);
    }
    if(level % 4 == 0){
        hitRange = getHitRange() + 1;
        critRange = getCritRange() + 1;
        values.put(KEY_HIT_RANGE, hitRange);
        values.put(KEY_CRIT_RANGE, critRange);
    }
    ourDatabase.update(DB_TBL, values, null, null );
}

private int getLargePots() {
    // TODO Auto-generated method stub
    open();
    Cursor cursor = ourDatabase.query(DB_TBL, new String[] {KEY_LARGE_POTS}, null, null, null, null, null);
    int largePots = cursor.getInt(0);
    cursor.close();
    close();
    return largePots;
}

private int getSmallPots() {
    // TODO Auto-generated method stub
    open();
    Cursor cursor = ourDatabase.query(DB_TBL, new String[] {KEY_SMALL_POTS}, null, null, null, null, null);
    int smallPots = cursor.getInt(0);
    cursor.close();
    close();
    return smallPots;
}

public void updateSmallPots() {
    // TODO Auto-generated method stub
    ContentValues values = new ContentValues();
    open();
    int smallPots = getSmallPots() + 1;
    int coins = getCoins() - 1; 
    values.put(KEY_SMALL_POTS, smallPots);
    values.put(KEY_COINS, coins);
    ourDatabase.update(DB_TBL, values, null, null);
    close();
}

public void updateLargePots(){
    ContentValues values = new ContentValues();
    open();
    int largePots = getLargePots() + 1;
    int coins = getCoins() - 2;
    values.put(KEY_LARGE_POTS, largePots);
    values.put(KEY_COINS, coins);
    ourDatabase.update(DB_TBL, values, null, null);
    close();
}
}

然后运行获得错误:

01-04 16:12:25.596: E/AndroidRuntime(29517): android.database.CursorIndexOutOfBoundsException: Index -1 requested, with a size of 1
01-04 16:12:25.596: E/AndroidRuntime(29517):    at android.database.AbstractCursor.checkPosition(AbstractCursor.java:580)
01-04 16:12:25.596: E/AndroidRuntime(29517):    at android.database.AbstractWindowedCursor.checkPosition(AbstractWindowedCursor.java:214)

2个回答

Kakalapa1986
Kakalapa1986   2013.01.05 15:52
已采纳

代码真长啊,

android.database.CursorIndexOutOfBoundsException: Index -1 requested, with a size of 1

你忘了调用cursor.moveToFirst(),还需要验证Cursor是否为空:

// Returns false if the Cursor cannot move to this position, i.e. empty
if(cursor.moveToFirst()) { 
    // Read data from the first row 
}
AnnBnnCnnD
AnnBnnCnnD 呵呵,谢谢了
大约 5 年之前 回复
xiaoxiaobian3310903
xiaoxiaobian3310903   2013.01.06 16:18

出现这种问题一般是你在执行查询的过程中没有将cursor的指针放到第一个位置,默认查询结束后位置是在-1的位置。

Csdn user default icon
上传中...
上传图片
插入图片
准确详细的回答,更有利于被提问者采纳,从而获得C币。复制、灌水、广告等回答会被删除,是时候展现真正的技术了!