Android SQLite cursoroutofboundsexception

Khi*_*uan -1 sqlite android

从SQLite获取对象(getRecipe()方法)的问题,因为我得到了一个cursoroutofbounds异常.

这是代码:

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Locale;

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

import com.apps.database.sqlite.model.Ingredients;
import com.apps.database.sqlite.model.Photo;
import com.apps.database.sqlite.model.Recipe;

public class RecipeDbHelper extends SQLiteOpenHelper {
    private static final String LOG = "DatabaseHelper";
    private static final String DATABASE_NAME = "RecipeManager";
    private static final int DATABASE_VERSION = 11;
    private static final String TABLE_RECIPE = "recipe";
    private static final String TABLE_INGREDIENT = "ingredients";
    private static final String TABLE_PHOTO = "photo";
    private static final String TABLE_PROCESSING = "processing";
    private static final String KEY_ID = "recipe_id";

    public RecipeDbHelper(Context context) {
        super(context, DATABASE_NAME, null, DATABASE_VERSION);

    }

    @Override
    public void onCreate(SQLiteDatabase db) {
        for (int i = 0; i < createTables().length; i++) {
            db.execSQL(createTables()[i]);
        }
    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        db.execSQL("DROP TABLE IF EXISTS " + TABLE_RECIPE);
        db.execSQL("DROP TABLE IF EXISTS " + TABLE_INGREDIENT);
        db.execSQL("DROP TABLE IF EXISTS " + TABLE_PHOTO);
        db.execSQL("DROP TABLE IF EXISTS " + TABLE_PROCESSING);

        // create new tables
        onCreate(db);

    }

    private String[] createTables() {
        String[] tables = new String[4];

        final String CREATE_TABLE_RECIPE = "CREATE TABLE " + TABLE_RECIPE + "("
                + KEY_ID + " INTEGER PRIMARY KEY, title TEXT)";
        final String CREATE_TABLE_INGREDIENTS = "CREATE TABLE "
                + TABLE_INGREDIENT + "(" + KEY_ID + " INTEGER REFERENCES "
                + TABLE_RECIPE + ", foodname TEXT, "
                + "amount real, measurement String, " + "PRIMARY KEY(" + KEY_ID
                + ", foodname))";
        final String CREATE_TABLE_PHOTO = "CREATE TABLE " + TABLE_PHOTO + "("
                + KEY_ID + " INTEGER PRIMARY KEY REFERENCES " + TABLE_RECIPE
                + ", pathfile TEXT)";

        final String CREATE_TABLE_PROCESSING = "CREATE TABLE "
                + TABLE_PROCESSING + "( " + KEY_ID
                + " INTEGER PRIMARY KEY, description TEXT)";

        tables[0] = CREATE_TABLE_RECIPE;
        tables[1] = CREATE_TABLE_INGREDIENTS;
        tables[2] = CREATE_TABLE_PHOTO;
        tables[3] = CREATE_TABLE_PROCESSING;
        return tables;
    }

    public boolean addRecipe(Recipe recipe) {

        for (Recipe rep : getAllRecipes()) {
            if (recipe.getTitle().equals(rep.getTitle())) {
                return false;
            }
        }
        SQLiteDatabase db = this.getWritableDatabase();
        ContentValues value = new ContentValues();

        value.put(KEY_ID, recipe.getRecipe_id());
        value.put("title", recipe.getTitle());
        db.insert(TABLE_RECIPE, null, value);
        db.close();
        return true;

    }

    public Recipe getRecipe(String name) {
        Recipe recipe = null;
        String KEY_TITLE = "title";
        SQLiteDatabase db = this.getReadableDatabase();
        String selectQuery = "SELECT * FROM " + TABLE_RECIPE
                + " WHERE "+ KEY_TITLE +" = '" + name + "'";
        Cursor cursor = db.rawQuery(selectQuery, null);
        recipe = new Recipe(cursor.getColumnIndex(KEY_ID),
                cursor.getString(cursor.getColumnIndex(KEY_TITLE)));

        cursor.close();
        return recipe;


          //REST OF THE CODE NOT INCLUDED
    }
}
Run Code Online (Sandbox Code Playgroud)

任何提示都会非常好!我真的陷入了从getRecipe()方法得到的异常.

Rag*_*dan 5

getRecipe()

 Cursor cursor = db.rawQuery(selectQuery, null); 
 if(cursor.moveToFirst())
 {
 recipe = new Recipe(cursor.getColumnIndex(KEY_ID),
 cursor.getString(cursor.getColumnIndex(KEY_TITLE))); 
 cursor.close();
 return recipe; 
 }
  return null;
Run Code Online (Sandbox Code Playgroud)

参考:

http://developer.android.com/reference/android/database/sqlite/SQLiteDatabase.html#rawQuery(java.lang.String,java.lang.String [])

正如Selvin和重新检查文档后所建议的那样

rawQuery 返回一个Cursor对象,该对象位于第一个条目之前. 所以游标不是null.

public abstract boolean moveToFirst ()

Added in API level 1
Move the cursor to the first row.

This method will return false if the cursor is empty.
Run Code Online (Sandbox Code Playgroud)

因此,如果cursor不为空,则返回true,否则返回false.所以我第一次发布时确实没有必要检查游标是否为null.

类似帖子

Android sqlite db.query导致CursorIndexOutOfBoundsException