1. Mitglieder surfen ohne Werbung auf Android-Hilfe.de! ✔ Jetzt kostenlos Mitglied in unserer Community werden.
  1. blackfire185, 24.03.2013 #1
    blackfire185

    blackfire185 Threadstarter Gewerbliches Mitglied

    Hallo,
    ich habe nach diesem Tutorial eine SQLite Datenbank erstellt und greife darauf zu.

    Wenn der folgende Code ausgeführt wird:
    PHP:
    public int getItemsCount() {
             
    String countQuery "SELECT  * FROM " TABLE_NAME;
             
    SQLiteDatabase db this.getReadableDatabase();
             
    Cursor cursor db.rawQuery(countQuerynull);
             
    cursor.close();
     
             return 
    cursor.getCount();
            }
    (in der SQL Helper Klasse)
    kommt diese Fehlermeldung:
    Code:
    03-24 20:35:59.840: E/AndroidRuntime(745): FATAL EXCEPTION: main
    03-24 20:35:59.840: E/AndroidRuntime(745): java.lang.RuntimeException: Unable to start activity ComponentInfo{de.droidenschmiede.firstai_erste_hilfe/de.droidenschmiede.firstai_erste_hilfe.MainActivity}: java.lang.IllegalStateException: attempt to re-open an already-closed object: android.database.sqlite.SQLiteQuery (mSql = SELECT  * FROM contacts) 
    03-24 20:35:59.840: E/AndroidRuntime(745): 	at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1647)
    03-24 20:35:59.840: E/AndroidRuntime(745): 	at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1663)
    03-24 20:35:59.840: E/AndroidRuntime(745): 	at android.app.ActivityThread.access$1500(ActivityThread.java:117)
    03-24 20:35:59.840: E/AndroidRuntime(745): 	at android.app.ActivityThread$H.handleMessage(ActivityThread.java:931)
    03-24 20:35:59.840: E/AndroidRuntime(745): 	at android.os.Handler.dispatchMessage(Handler.java:99)
    03-24 20:35:59.840: E/AndroidRuntime(745): 	at android.os.Looper.loop(Looper.java:123)
    03-24 20:35:59.840: E/AndroidRuntime(745): 	at android.app.ActivityThread.main(ActivityThread.java:3683)
    03-24 20:35:59.840: E/AndroidRuntime(745): 	at java.lang.reflect.Method.invokeNative(Native Method)
    03-24 20:35:59.840: E/AndroidRuntime(745): 	at java.lang.reflect.Method.invoke(Method.java:507)
    03-24 20:35:59.840: E/AndroidRuntime(745): 	at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:839)
    03-24 20:35:59.840: E/AndroidRuntime(745): 	at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:597)
    03-24 20:35:59.840: E/AndroidRuntime(745): 	at dalvik.system.NativeStart.main(Native Method)
    03-24 20:35:59.840: E/AndroidRuntime(745): Caused by: java.lang.IllegalStateException: attempt to re-open an already-closed object: android.database.sqlite.SQLiteQuery (mSql = SELECT  * FROM contacts) 
    03-24 20:35:59.840: E/AndroidRuntime(745): 	at android.database.sqlite.SQLiteClosable.acquireReference(SQLiteClosable.java:34)
    03-24 20:35:59.840: E/AndroidRuntime(745): 	at android.database.sqlite.SQLiteQuery.fillWindow(SQLiteQuery.java:67)
    03-24 20:35:59.840: E/AndroidRuntime(745): 	at android.database.sqlite.SQLiteCursor.fillWindow(SQLiteCursor.java:287)
    03-24 20:35:59.840: E/AndroidRuntime(745): 	at android.database.sqlite.SQLiteCursor.getCount(SQLiteCursor.java:268)
    03-24 20:35:59.840: E/AndroidRuntime(745): 	at de.droidenschmiede.firstai_erste_hilfe.SQLHelper.getItemsCount(SQLHelper.java:121)
    03-24 20:35:59.840: E/AndroidRuntime(745): 	at de.droidenschmiede.firstai_erste_hilfe.MainActivity.einlesenDaten(MainActivity.java:54)
    03-24 20:35:59.840: E/AndroidRuntime(745): 	at de.droidenschmiede.firstai_erste_hilfe.MainActivity.onCreate(MainActivity.java:29)
    03-24 20:35:59.840: E/AndroidRuntime(745): 	at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1047)
    03-24 20:35:59.840: E/AndroidRuntime(745): 	at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1611)
    03-24 20:35:59.840: E/AndroidRuntime(745): 	... 11 more
    Wohlgemerkt, wenn ich einen Breakpoint auf das return Statement setzte:
    PHP:
    return cursor.getCount();
    wird alles bis zum Breakpoint korrekt ausgeführt und danach kommt eben diese Exception.

    Nach Googeln heißt es in Stackoverflow, dass auf den Cursor nur einmal zugegriffen werden darf oder so. Ich verstehe aber nicht, was an dem Tutorial nicht funktioniert, bzw. wie ich die Lösung von Stackoverflow einbauen soll?

    Danke für schnelle Antworten
    Gruß

    Code SQLHelper:
    PHP:
    public class SQLHelper extends SQLiteOpenHelper {
         
        public 
    SQLHelper(Context contextString nameCursorFactory factory,
                
    int version) {
            
    super(contextnamefactoryversion);
            
    // TODO Auto-generated constructor stub
        
    }

        
    // All Static variables
        // Database Version
        
    private static final int DATABASE_VERSION 1;
     
        
    // Database Name
        
    private static final String DATABASE_NAME "firstai";
     
        
    // Contacts table name
        
    private static final String TABLE_NAME "contacts";
     
       
     
       
     
        
    // Creating Tables
        
    @Override
        
    public void onCreate(SQLiteDatabase db) {
            
    String CREATE_TABLE "CREATE TABLE " TABLE_NAME "("
                   
    +" id INTEGER PRIMARY KEY, titel TEXT,"
                   
    +" content TEXT)";
            
    db.execSQL(CREATE_TABLE);
            
    db.close();
        }
     
        
    // Upgrading database
        
    @Override
        
    public void onUpgrade(SQLiteDatabase dbint oldVersionint newVersion) {
            
    // Drop older table if existed
            
    db.execSQL("DROP TABLE IF EXISTS " TABLE_NAME);
     
            
    // Create tables again
            
    onCreate(db);
        }
        
     
    // Adding new item
        
    public void addItem(item Item) {
             
    SQLiteDatabase db this.getWritableDatabase();
             
                
    ContentValues values = new ContentValues();
                
    values.put("titel"Item.getTitel()); // Contact Name
                
    values.put("content"Item.getContent()); // Contact Phone Number
             
                // Inserting Row
                
    db.insert(TABLE_NAMEnullvalues);
                
    db.close(); // Closing database connection
            
        
    }
        
     
    // Getting single item
        
    public item getItem(int id) {
            
    SQLiteDatabase db this.getReadableDatabase();
             
            
    Cursor cursor db.query(TABLE_NAME, new String[] { "id",
                    
    "titel""content" }, "id" "=?",
                    new 
    String[] { String.valueOf(id) }, nullnullnullnull);
            if (
    cursor != null)
                
    cursor.moveToFirst();
         
            
    item singleItem = new item(Integer.parseInt(cursor.getString(0)),
                    
    cursor.getString(1), cursor.getString(2));
            
    // return contact
            
    return singleItem;
            
            }
         
        
    // Getting All items
        
    public List<itemgetallItems() {
                List<
    itemtemplist = new ArrayList<item>();
                
    // Select All Query
                
    String selectQuery "SELECT  * FROM " TABLE_NAME;
             
                
    SQLiteDatabase db this.getWritableDatabase();
                
    Cursor cursor db.rawQuery(selectQuerynull);
             
                
    // looping through all rows and adding to list
                
    if (cursor.moveToFirst()) {
                    do {
                        
    item contact = new item();
                        
    contact.setID(Integer.parseInt(cursor.getString(0)));
                        
    contact.setTitel(cursor.getString(1));
                        
    contact.setContent(cursor.getString(2));
                        
    // Adding contact to list
                        
    templist.add(contact);
                    } while (
    cursor.moveToNext());
                }
             
              
    cursor.close();
              
    db.close();
                return 
    templist;
            }
         
        
    // Getting items Count
        
    public int getItemsCount() {
             
    String countQuery "SELECT  * FROM " TABLE_NAME;
             
    SQLiteDatabase db this.getReadableDatabase();
             
    Cursor cursor db.rawQuery(countQuerynull);
             
    cursor.close();
     
             return 
    cursor.getCount();
            }

    }
    Code MainActivity:
    PHP:
    public void einlesenDaten(){
     
            
    // Reading all contacts
            
    Log.d(LOG"Reading all contacts..");
            List<
    itemcontacts db.getallItems();       
     
            for (
    item cn contacts) {
                
    String log "Id: "+cn.getID()+" ,Titel: " cn.getTitel() + " ,Content: " cn.getContent();
                    
    // Writing Contacts to log
            
    Log.d(LOGlog);
            
            }
            
    Log.d(LOG"getCount");
            
    int count db.getItemsCount();
            
    Log.d(LOGString.valueOf(count));
     
  2. deek, 24.03.2013 #2
    deek

    deek Android-Experte

    Du schließt deinen Cursor mit cursor.close(). Danach willst du aber nochmal eine Operation auf dem Cursor durchführen.

    probiers mal so:
    Code:
    int itemCount = cursor.getCount();
    cursor.close();
    return itemCount;
    
     
    blackfire185 bedankt sich.
  3. blackfire185, 25.03.2013 #3
    blackfire185

    blackfire185 Threadstarter Gewerbliches Mitglied

    Das scheint logisch und zu einfach zu sein. Ändert nichts.
    Weitere Ideen??

    Trotzdem Danke

    EDIT: OK, ich habe festgestellt, das im Tutorial schon Fehler liegen. Dort wird in der Helper Klasse an unpassenden stellen die Database geclosed.

    Jetzt versuche ich ein Item auszulesen:
    PHP:
    Item db.getItem(i);
    PHP:
    Cursor cursor db.query(TABLE_NAME, new String[] { "id",
                    
    "titel""content" }, "id" "=?",
                    new 
    String[] { String.valueOf(id) }, nullnullnullnull);
    An diesem Punkt wird eine
    Code:
    03-25 19:36:06.962: E/AndroidRuntime(925): java.lang.RuntimeException: Unable to start activity ComponentInfo{de.droidenschmiede.firstai_erste_hilfe/de.droidenschmiede.firstai_erste_hilfe.MainActivity}: android.database.sqlite.SQLiteException: bind or column index out of range: handle 0x2a50e8
    
    Exception geworfen.

    Dies wird allerdings schon beim ersten getItem Aufruf geworfen, ich glaube der Fehler könnte in
    Code:
    "id" + "=?"
    liegen. Das ist der String, in dem die Selection angegeben wird.

    Danke
     
    Zuletzt bearbeitet: 25.03.2013
  4. deek, 25.03.2013 #4
    deek

    deek Android-Experte

    Hmm sorry, keine Idee gerade. Könntest du etwas mehr Code (also komplette Methode, mit Zeilennummer der ersten angegebenen Zeile) und den kompletten Stacktrace der Exception noch anhängen?

    Noch ein Hinweis fernab des eigentlichen Problems:
    Man sollte bei Android die id Spaltem immer _id nennen (mit Unterstrich vorne dran). Wenn du mal einen ContentProvider schreiben willst erleichtert das die Sache, da dieser genau das erwartet. Ansonsten musst du später wenn es soweit ist das ganze ändern und die Datenbank kompliziert migrieren (so aktuell bei uns geschehen).
     
  5. blackfire185, 26.03.2013 #5
    blackfire185

    blackfire185 Threadstarter Gewerbliches Mitglied

    OK. Danke für den Hinweis.
    Ich habe noch einige Stunden experimentiert und am Ende festgestellt, dass es in meiner SQLite keine id = 0 gibt, sondern sie bei eins anfängt. Außerdem ist das Tutorial fehlerhaltig, also nicht zu empfehlen.

    Das mit den Unterstrichen, gut zu wissen, habe mich schon gewundert.
    Danke erstmal.
    Gruß
     
Du betrachtest das Thema "SQL Lite Exception:Illegal State" im Forum "Android App Entwicklung",
  1. Android-Hilfe.de verwendet Cookies um Inhalte zu personalisieren und dir den bestmöglichen Service zu gewährleisten. Wenn du auf der Seite weitersurfst stimmst du der Cookie-Nutzung zu.  Ich stimme zu.