SQL Lite Exception:Illegal State

blackfire185

blackfire185

Stammgast
40
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(countQuery, null);
         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 context, String name, CursorFactory factory,
			int version) {
		super(context, name, factory, version);
		// 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 db, int oldVersion, int 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_NAME, null, values);
    	    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) }, null, null, null, null);
        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<item> getallItems() {
    	    List<item> templist = new ArrayList<item>();
    	    // Select All Query
    	    String selectQuery = "SELECT  * FROM " + TABLE_NAME;
    	 
    	    SQLiteDatabase db = this.getWritableDatabase();
    	    Cursor cursor = db.rawQuery(selectQuery, null);
    	 
    	    // 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(countQuery, null);
         cursor.close();
 
         return cursor.getCount();
		}

}

Code MainActivity:
PHP:
public void einlesenDaten(){
 
        // Reading all contacts
        Log.d(LOG, "Reading all contacts..");
        List<item> contacts = db.getallItems();       
 
        for (item cn : contacts) {
            String log = "Id: "+cn.getID()+" ,Titel: " + cn.getTitel() + " ,Content: " + cn.getContent();
                // Writing Contacts to log
        Log.d(LOG, log);
        
        }
        Log.d(LOG, "getCount");
        int count = db.getItemsCount();
        Log.d(LOG, String.valueOf(count));
 
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;
 
  • Danke
Reaktionen: blackfire185
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) }, null, null, null, null);
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:
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).
 
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ß
 

Ähnliche Themen

M
  • mafoma63
Antworten
2
Aufrufe
762
swa00
swa00
B
Antworten
3
Aufrufe
1.307
swa00
swa00
R
Antworten
6
Aufrufe
1.014
swa00
swa00
Zurück
Oben Unten