Autore Topic: Problemi con i cursori  (Letto 723 volte)

Offline mangusto

  • Utente normale
  • ***
  • Post: 152
  • Respect: +5
    • Google+
    • Mostra profilo
  • Dispositivo Android:
    ZTE Blade
  • Play Store ID:
    Leonardo Preti
  • Sistema operativo:
    Windows 7
Problemi con i cursori
« il: 28 Marzo 2013, 11:02:28 CET »
0
Sto lavorando con un database; all'interno di questo database ho due tabelle ma per ora sto lavorando solo su una e ho definito alcuni metodi per ottenere tutte le tuple o una parte di esse, in base a query di selezione. Utilizzando i log so che i metodi trovano il numero corretto di righe. Per visualizzare i risultati delle query per ora sto utilizzando un semplice toast che mi mostra a schermo alcune informazioni di ogni tupla.
Il problema è il seguente: facendo partire la query che mi restituisce tutte le righe (ovvero 6 righe) non ho alcun problema e le informazioni vengono visualizzate correttamente; se faccio partire la query che mi restituisce tutte le righe in cui " Categoria = 'Antipasto' " (ovvero 2 righe) il programma va in crash con problema android.database.CursorIndexOutOfBoundsException: Index 2 requested, with a size of 2.


Questi i vari pezzi di codice:
Lista.java
Codice (Java): [Seleziona]
public class Lista extends SherlockActivity {
       
        Database dbRicette = new Database(this);
       
        @Override
        public void onCreate(Bundle savedInstanceState){
                super.onCreate(savedInstanceState);
                setContentView(R.layout.layout_lista);
               
                // Ottenere informazioni passate da Indice.class
                String pkg = getPackageName();
                String title = getIntent().getStringExtra(pkg + ".category");
               
                // Impostazione della ActionBar
                getSupportActionBar().setDisplayHomeAsUpEnabled(true);
                getSupportActionBar().setTitle(title);
               
                dbRicette.open();
                Cursor c = dbRicette.getAntipasti(); // Se qui richiamassi il metodo dbRicette.getAllRecipes() non andrebbe in crash
                c.moveToFirst();


                for(int i  = 0 ; i < 6 ; i++) {
                        Toast.makeText(this, "ID_RICETTA = " + c.getString(0) + "\n" + "TITOLO_RICETTA = " + c.getString(2)
                        + "\n" + "INGREDIENTI = " + c.getString(3), Toast.LENGTH_LONG).show(); // Questa è la riga 60 di Lista.java
                        c.moveToNext();
                }
        }
Database.java
Codice (Java): [Seleziona]
public class Database {
       
        Context mContext;      
        DatabaseHelper mDbHelper;
        SQLiteDatabase mDb;
        String[] s = new String [] {MetaData.KEY_ID, MetaData.KEY_TITLE, MetaData.KEY_DIFFICULTY, MetaData.KEY_TIME, MetaData.KEY_VEGETARIAN};


        private static final String DATABASE_NAME = "RicettarioTascabile"; // Nome DB
        private static final int DATABASE_VERSION = 8; // Versione DB
       
        public Database(Context context) {
                this.mContext = context;
                mDbHelper = new DatabaseHelper(context);
        }
       
        // Metodo per aprire il DB
        public void open() throws SQLException {
                mDb = mDbHelper.getWritableDatabase();
        }
       
        // Metodo per chiudere il DB
        public void close() {
                mDb.close();
        }
       


        // Classe che definisce i metadati della tabella
        static class MetaData {
               
                static final String TABLE_RECIPES = "Recipes";
                static final String TABLE_STARRED = "Favorites";
               
                static final String KEY_ID = "_id";
                static final String KEY_TITLE = "title";
                static final String KEY_INGREDIENTS = "ingredients";
                static final String KEY_TIME = "time";
                static final String KEY_PEOPLE = "people";
                static final String KEY_WINE = "wine";
                static final String KEY_SUGGESTIONS = "suggestions";
                static final String KEY_DIRECTIONS = "directions";
                static final String KEY_AUTHOR = "author";
                static final String KEY_DIFFICULTY = "difficulty";
                static final String KEY_CATEGORY = "category";
                static final String KEY_VEGETARIAN = "veggie";
                static final String KEY_NEW = "new";
                static final String KEY_IMAGE = "image";
               
                static final String KEY_STARRED = "starred";
               
        }
       
        // Definizione delle specifiche della tabella RICETTE
        private static final String DATABASE_RECIPES_CREATE = "CREATE TABLE IF NOT EXISTS "
                + MetaData.TABLE_RECIPES + " ("
                + MetaData.KEY_ID + " integer primary key autoincrement, "
                + MetaData.KEY_NEW + " boolean not null, "
                + MetaData.KEY_TITLE + " text not null, "
                + MetaData.KEY_INGREDIENTS + " text not null, "
                + MetaData.KEY_TIME + " text not null, "
                + MetaData.KEY_PEOPLE + " text not null, "
                + MetaData.KEY_WINE + " text, "
                + MetaData.KEY_SUGGESTIONS + " text, "
                + MetaData.KEY_DIRECTIONS + " text not null, "
                + MetaData.KEY_AUTHOR + " text, "
                + MetaData.KEY_DIFFICULTY + " text not null, "
                + MetaData.KEY_CATEGORY + " text not null, "
                + MetaData.KEY_VEGETARIAN + " boolean, "       
                + MetaData.KEY_IMAGE + " text)";
       
        // Definizione delle specifiche della tabella PREFERITI
        private static final String DATABASE_STARRED_CREATE = "CREATE TABLE IF NOT EXISTS "
                + MetaData.TABLE_STARRED + " ("
                + MetaData.KEY_ID + "integer primary key autoincrement, "
                + MetaData.KEY_STARRED + "boolean not null)";
       
        // Metodo per aggiungere una ricetta alla tabella RICETTE
        public long addRecipe(int _id, boolean _new, String _title, String _ingredients, String _time, String _people, String _wine, String _suggestions,
                        String _directions, String _author, String _difficulty, String _category, boolean _vegetarian, String _image)
    {
        ContentValues initialValues = new ContentValues();
       
        initialValues.put(MetaData.KEY_ID, _id);
        initialValues.put(MetaData.KEY_NEW, _new);
        initialValues.put(MetaData.KEY_TITLE, _title);
        initialValues.put(MetaData.KEY_INGREDIENTS, _ingredients);
        initialValues.put(MetaData.KEY_TIME, _time);
        initialValues.put(MetaData.KEY_PEOPLE, _people);
        initialValues.put(MetaData.KEY_WINE, _wine);
        initialValues.put(MetaData.KEY_SUGGESTIONS, _suggestions);
        initialValues.put(MetaData.KEY_DIRECTIONS, _directions);
        initialValues.put(MetaData.KEY_AUTHOR, _author);
        initialValues.put(MetaData.KEY_DIFFICULTY, _difficulty);
        initialValues.put(MetaData.KEY_CATEGORY, _category);
        initialValues.put(MetaData.KEY_VEGETARIAN, _vegetarian);
        initialValues.put(MetaData.KEY_IMAGE, _image);
       
        return mDb.insert(MetaData.TABLE_RECIPES, null, initialValues);
    }
       
        // Query per avere tutte le tuple della tabella RICETTE
        public Cursor getAllRecipes() {
                Cursor mCursor = mDb.query(MetaData.TABLE_RECIPES, null, null, null, null, null, MetaData.KEY_TITLE + " ASC", null);
                Log.d("getAllRecipes","NUMERO RICETTE = " + mCursor.getCount());
                return mCursor;
        }
       
        // Query per avere tutti gli NATIPASTI della tabella RICETTE   
        public Cursor getAntipasti() {
                Cursor mCursor = mDb.query(MetaData.TABLE_RECIPES,
                                null,   MetaData.KEY_CATEGORY + " = 'Antipasti'", null, null, null, MetaData.KEY_TITLE + " ASC", null);


                Log.d("getAntipasti","NUMERO ANTIPASTI = " + mCursor.getCount());
               
                return mCursor;
        }
       
        private static class DatabaseHelper extends SQLiteOpenHelper {
               
                public DatabaseHelper(Context context) {
                        super(context, DATABASE_NAME, null, DATABASE_VERSION);
                }
               
                // Se è la prima esecuzione, viene creato il DB
                @Override
                public void onCreate(SQLiteDatabase db) {
                        db.execSQL(DATABASE_RECIPES_CREATE);
                        db.execSQL(DATABASE_STARRED_CREATE);
                }
               
                // Se il DB è stato aggiornato, viene cancellato quello vecchio e sosituito da quello nuovo
                @Override
                public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
                        Log.w("dB update", "Upgrading database from version " + oldVersion + " to " + newVersion);
                        db.execSQL("DROP TABLE IF EXISTS " + MetaData.TABLE_RECIPES);
                        onCreate(db);
                }
        }
Logcat

Codice: [Seleziona]

03-28 10:46:19.486: E/AndroidRuntime(15898): FATAL EXCEPTION: main
03-28 10:46:19.486: E/AndroidRuntime(15898): java.lang.RuntimeException: Unable to start activity ComponentInfo{it.mangusto.newfork/it.mangusto.newfork.Lista}: android.database.CursorIndexOutOfBoundsException: Index 2 requested, with a size of 2
03-28 10:46:19.486: E/AndroidRuntime(15898):         at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2180)
03-28 10:46:19.486: E/AndroidRuntime(15898):         at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2230)
03-28 10:46:19.486: E/AndroidRuntime(15898):         at android.app.ActivityThread.access$600(ActivityThread.java:141)
03-28 10:46:19.486: E/AndroidRuntime(15898):         at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1234)
03-28 10:46:19.486: E/AndroidRuntime(15898):         at android.os.Handler.dispatchMessage(Handler.java:99)
03-28 10:46:19.486: E/AndroidRuntime(15898):         at android.os.Looper.loop(Looper.java:137)
03-28 10:46:19.486: E/AndroidRuntime(15898):         at android.app.ActivityThread.main(ActivityThread.java:5041)
03-28 10:46:19.486: E/AndroidRuntime(15898):         at java.lang.reflect.Method.invokeNative(Native Method)
03-28 10:46:19.486: E/AndroidRuntime(15898):         at java.lang.reflect.Method.invoke(Method.java:511)
03-28 10:46:19.486: E/AndroidRuntime(15898):         at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:793)
03-28 10:46:19.486: E/AndroidRuntime(15898):         at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:560)
03-28 10:46:19.486: E/AndroidRuntime(15898):         at dalvik.system.NativeStart.main(Native Method)
03-28 10:46:19.486: E/AndroidRuntime(15898): Caused by: android.database.CursorIndexOutOfBoundsException: Index 2 requested, with a size of 2
03-28 10:46:19.486: E/AndroidRuntime(15898):         at android.database.AbstractCursor.checkPosition(AbstractCursor.java:424)
03-28 10:46:19.486: E/AndroidRuntime(15898):         at android.database.AbstractWindowedCursor.checkPosition(AbstractWindowedCursor.java:136)
03-28 10:46:19.486: E/AndroidRuntime(15898):         at android.database.AbstractWindowedCursor.getString(AbstractWindowedCursor.java:50)
03-28 10:46:19.486: E/AndroidRuntime(15898):         at it.mangusto.newfork.Lista.onCreate(Lista.java:60)
03-28 10:46:19.486: E/AndroidRuntime(15898):         at android.app.Activity.performCreate(Activity.java:5104)
03-28 10:46:19.486: E/AndroidRuntime(15898):         at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1080)
03-28 10:46:19.486: E/AndroidRuntime(15898):         at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2144)
03-28 10:46:19.486: E/AndroidRuntime(15898):         ... 11 more
Qualcuno mi può spiegare concettualmente qual è l'errore?

Offline Nicola_D

  • Moderatore
  • Utente storico
  • *****
  • Post: 2479
  • SBAGLIATO!
  • Respect: +323
    • Github
    • Google+
    • nicoladorigatti
    • Mostra profilo
  • Dispositivo Android:
    Nexus 6p, Nexus 4, Nexus S, Nexus 7(2012)
  • Sistema operativo:
    Windows 7
Re:Problemi con i cursori
« Risposta #1 il: 28 Marzo 2013, 11:57:54 CET »
+1
è un errore analogo al "ArrayIndexOutOfBoundException" stai cercando di leggere un elemento che sta fuori dall'array.
se l'array/cursore è di due elementi, gli elementi saranno:
array[0]
array[1]

IMPORTANTE:NON RISPONDO A PROBLEMI VIA MESSAGGIO PRIVATO
LOGCAT: Non sai cos'è? -> Android Debug Bridge | Android Developers
               Dov'è in Eclipse? -> Window -> Open Prospective -> DDMS e guarda in basso!
[Obbligatorio] Logcat, questo sconosciuto! (Gruppo AndDev.it LOGTFO) - Android Developers Italia

Offline mangusto

  • Utente normale
  • ***
  • Post: 152
  • Respect: +5
    • Google+
    • Mostra profilo
  • Dispositivo Android:
    ZTE Blade
  • Play Store ID:
    Leonardo Preti
  • Sistema operativo:
    Windows 7
Re:Problemi con i cursori
« Risposta #2 il: 28 Marzo 2013, 12:01:12 CET »
0
è un errore analogo al "ArrayIndexOutOfBoundException" stai cercando di leggere un elemento che sta fuori dall'array.
Ti ringrazio infinitamente, ho sbattuto la testa su questo problema per due giorni senza venirne a capo quando la soluzione era così facile!