1. Nimm jetzt an unserem 2. ADVENT-Gewinnspiel teil - Alle Informationen findest Du hier!

Cursor schließen?

Dieses Thema im Forum "Android App Entwicklung" wurde erstellt von so.r.u, 08.03.2010.

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

    so.r.u Threadstarter Neuer Benutzer

    Beiträge:
    22
    Erhaltene Danke:
    0
    Registriert seit:
    11.02.2010
    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

    Beiträge:
    3,072
    Erhaltene Danke:
    1,138
    Registriert seit:
    27.02.2009
    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

    Beiträge:
    22
    Erhaltene Danke:
    0
    Registriert seit:
    11.02.2010
    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

    Beiträge:
    3,072
    Erhaltene Danke:
    1,138
    Registriert seit:
    27.02.2009
    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

    Beiträge:
    22
    Erhaltene Danke:
    0
    Registriert seit:
    11.02.2010
    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

    Beiträge:
    22
    Erhaltene Danke:
    0
    Registriert seit:
    11.02.2010
    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(); }
    }
    
     

Diese Seite empfehlen