1. so.r.u, 08.03.2010 #1
    so.r.u

    so.r.u Threadstarter Neuer Benutzer

    Hallo!

    Ich habe eine Datenbankanfrage in meinem Programm, bekommen aber ständig IllegalStateExceptions wegen einem Cursor. Dabei schließe ich nach jeder Anfrage diesen Cursor:

    Code:
     public WayPoint getLatestWayPoint(int route_id) {
            Cursor c = null;
            WayPoint w = null;
            try {
                c = db.query(WAYPOINTS, new String[] { "max(timestamp)" },
                        "route_id = ?", new String[] { route_id + "" }, null, null,
                        " timestamp ASC");
    
                (...)
    
                w = new WayPoint(id, route_id, timestamp, latitude, longitude, comment);
            } catch (SQLException e) {
                Log.e(TAG, "Database error fetching latest waypoint for route with id = " + route_id); }
            if ( c != null ) {
                c.close(); 
            }
            return w;
        }
     
    Der c.close-Fall wird auch jedes Mal durchlaufen, nur danach ist c immer noch einSQLiteCursor, sollte es dann nicht null sein? Woran könnte das denn liegen? Ach ja das Ergebnis der Abfrage ist richtig.
     
  2. SeraphimSerapis, 08.03.2010 #2
    SeraphimSerapis

    SeraphimSerapis Android-Guru

    ich glaube c.close() entfernt nicht die referenz auf den db.query(..), sondern deaktiviert ihn nur dauerhaft.
     
  3. so.r.u, 08.03.2010 #3
    so.r.u

    so.r.u Threadstarter Neuer Benutzer

    Aber was heißt deaktiviert? Laut API macht close:

    Deactivate:

    Was muss man dann aufrufen, damit der Cursor "finalized" ist, d.h. dass alle Ressourcen freigegeben werden?
     
  4. SeraphimSerapis, 08.03.2010 #4
    SeraphimSerapis

    SeraphimSerapis Android-Guru

    Steht doch da - close reicht - am besten innerhalb einer finally.
     
  5. so.r.u, 08.03.2010 #5
    so.r.u

    so.r.u Threadstarter Neuer Benutzer

    Aber close wird ja aufgerufen, scheinbar is aber noch nicht alles freigegeben, sonst würds ja nicht zu einer IllegalStateException kommen, oder?
     
  6. so.r.u, 06.04.2010 #6
    so.r.u

    so.r.u Threadstarter Neuer Benutzer

    Hab endlich den Fehler gefunden, ich hab den Cursor zweimal benutzt, d.h. ungefähr sowas gemacht

    ...
    Code:
    c = db.query(WAYPOINTS, new String[] { "max(timestamp)" },
                        "route_id = ?", new String[] { route_id + "" }, null, null,
                        " timestamp ASC");
    if (c.moveToFirst()) {
         int timeCol = c.getColumnIndex("max(timestamp)");
         last_time = c.getString(timeCol);
    }
    c = db.query(WAYPOINTS, null, "route_id = ? and timestamp = ?",
                        new String[] { route_id + "", last_time + "" }, null, null,
                        " timestamp ASC");
    
    ...

    D.h. einem Cursor zwei Queries zugewiesen, wenn man vor dem zweiten query() c.close() aufruft (und am Ende nochmal) dann klappts!
    Oder am besten zwei Cursor erstellen, jeweils einen für ein query verwenden, und wie SeraphimSerapis vorgeschlagen hat das in ein finally verpacken:

    Code:
    Cursor c = null;
    Cursor c2 = null;
    
    try {
        String last_time = "";
        c = db.query(WAYPOINTS, new String[] { "max(timestamp)" },
                        "route_id = ?", new String[] { route_id + "" }, null, null,
                        " timestamp ASC");
        if (c.moveToFirst()) {
            int timeCol = c.getColumnIndex("max(timestamp)");
            last_time = c.getString(timeCol);
         }
         c2 = db.query(WAYPOINTS, null, "route_id = ? and timestamp = ?",
                        new String[] { route_id + "", last_time + "" }, null, null,
                        " timestamp ASC");
         if (c2.moveToFirst()) {
         //do something
    } catch (SQLException e) {
         Log.e(TAG, "e.getMessage()); }
    finally{
         if ( c != null ) { c.close(); }
         if ( c2 != null ) { c2.close(); }
    }