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

Cursor schließen

Dieses Thema im Forum "Android App Entwicklung" wurde erstellt von zblack, 09.02.2012.

  1. zblack, 09.02.2012 #1
    zblack

    zblack Threadstarter Gast

    hallo Android Freunde,
    in meiner App habe ich mehrere Klassen wo ich auf die Datenbank zugreife. in jeder Klasse habe ich die Funktion onDestroy () umgeschrieben in
    @Override
    protected void onDestroy() {
    // TODO Auto-generated method stub
    super.onDestroy();
    c.close();
    baseHelper.close();
    }
    das funktioniert aber, ich kriege komischerweise nur bei einer Klasse

    02-09 14:03:16.229: E/Database(2219): close() was never explicitly called on database '/data/data/de.meinautohaus/databases/autohausDB.db'

    wobei die Funktion onDestroy () auch in der Klasse ist.
    Bei allen anderen Klassen klappt es ohne Probleme
     
  2. the_alien, 09.02.2012 #2
    the_alien

    the_alien Android-Lexikon

    Beiträge:
    1,559
    Erhaltene Danke:
    184
    Registriert seit:
    04.05.2009
    Ist diese eine Klasse auch eine Activity?
     
  3. zblack, 09.02.2012 #3
    zblack

    zblack Threadstarter Gast

    ListActivity
     
  4. JanF, 09.02.2012 #4
    JanF

    JanF Android-Experte

    Beiträge:
    594
    Erhaltene Danke:
    79
    Registriert seit:
    31.03.2011
    Führe
    Code:
    super.onDestroy()
    Mal als letztes aus. Die Activity wird sonst zerstört, bevor der ganze Code ausgeführt wurde.
     
  5. mradlmaier, 11.02.2012 #5
    mradlmaier

    mradlmaier Gewerbliches Mitglied

    Beiträge:
    158
    Erhaltene Danke:
    17
    Registriert seit:
    28.10.2011
    Auf stackoverflow.com gibt es unzählige Fragen zu dem Thema. Wundert mich dass dieses Thema hier so selten auftaucht.

    Im Prinzip gehts darum, dass Du einen Cursor oder db leak hast. Klassischer Memoryleak. Da Java einen garbage collector hat, ist dass natürlich kein fataler Fehler, allerdings denke ich schon, dass Du den beheben solltest.

    Erstmal:
    Dieser Fehler taucht erst im Error Log auf seit startManagingCursor(Cursor cursor) deprecated ist. (Seit Honeycomb).
    Bis Honeycomb sollte obige Methode den Cursor an den Lebenszyklus der Activity binden. Dadurch sollte das Schliessen des Cursor automatisch geschehen. Hat bei mir (und wohl auch bei anderen) nie richtig funtioniert, daher wurde die Methode deprecated.
    Stattdessen soll jetzt die CursorLoader API verwendet werden (ab Honeycomb) und für ältere API Levels in Verbindung mit der Android Combatibility Library (und Reflections API).
    Das finde ich aber ziemlich Overkill. Zu dem gilt die Reflections API nicht als besonders performant.
    Leider habe ich für diesen Error keine richtige 100% Lösung gefunden, ausser folgende:
    db open
    cursor query
    Array mit cursor daten füllen
    cursor close
    db close
    Array mittels ArrayAdapter an die ListView binden

    Alles unmittelbar, so hast Du 100% Kontrolle das nix leaked.

    Hat natürlich einen massiven Nachteil:
    Listviews können dann natürlich nicht direkt mit Cursor gefüllt werden. Muss dann einen Array mit dem Cursor füllen und den Array via ArrayAdapter mit der ListView. Nix mit Live Data! Bei reinem Lesezugriff funktioniert das natürlich, und Du brauchst dann auch keinen SimpleCursorAdapter mehr. (Der ist nähmlich seit Honeycomb auch deprecated) .
    Zweiter Nachteil natürlich:
    Das Öffnen der db und des cursor ist eine teuere Operation. Wenn Du das oft machen musst, natürlich suboptimal.

    Vorteile:
    Keine Cursor oder db Leaks mehr und keine Errors im Log.
    Keine verwendung von deprecated Methoden oder Klassen.

    Wenn hier jemand weiss, wie man den Cursor/db elegant ohne Leaks an den Lebenszyklus bindet, wäre ich für Erleuchtung sehr dankbar...
     
    Zuletzt bearbeitet: 11.02.2012
  6. mradlmaier, 11.02.2012 #6
    mradlmaier

    mradlmaier Gewerbliches Mitglied

    Beiträge:
    158
    Erhaltene Danke:
    17
    Registriert seit:
    28.10.2011
    Beachte: Da dieser Fehler durch den Garbage Collector ausgelöst wird, ist es leider nicht ganz eindeutig, wo der Cursor leaked. Kannste leicht mit verschiedenen Androiden testen: Je weniger Speicher, desto häufiger läuft der gc, und desto öfter steht der Error im Error Log.
     

Diese Seite empfehlen