Cursor schließen

Z

zblack

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
 
Ist diese eine Klasse auch eine Activity?
 
ListActivity
 
Führe
Code:
super.onDestroy()
Mal als letztes aus. Die Activity wird sonst zerstört, bevor der ganze Code ausgeführt wurde.
 
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:
zblack schrieb:
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

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.
 

Ähnliche Themen

S
  • SlayNox
Antworten
0
Aufrufe
681
SlayNox
S
S
Antworten
2
Aufrufe
984
stikker
S
E
Antworten
10
Aufrufe
1.352
enrem
E
Zurück
Oben Unten