Nachdem ich einige Probleme hatte, denke ich, dass ich verstanden habe, warum ich etwas falsch gemacht habe.
Ich hatte eine Datenbank-Wrapper-Klasse geschrieben, die eine close()
die den Helfer als Spiegel von open()
die getWriteableDatabase aufriefen, und sind dann zu einer ContentProvider
. Das Modell für ContentProvider
verwendet nicht SQLiteDatabase.close()
was meiner Meinung nach ein wichtiger Hinweis ist, denn der Code verwendet getWriteableDatabase
In einigen Fällen hatte ich immer noch direkten Zugriff (Abfragen zur Bildschirmvalidierung), so dass ich auf ein getWriteableDatabase/rawQuery-Modell umgestiegen bin.
Ich verwende ein Singleton und es gibt den etwas ominösen Kommentar in der Close-Dokumentation
Schließen Sie 何れも Datenbankobjekt öffnen
(Fettdruck von mir).
Ich hatte also zeitweise Abstürze, bei denen ich Hintergrund-Threads für den Zugriff auf die Datenbank benutzte, die zur gleichen Zeit wie die Vordergrund-Threads liefen.
Ich denke also close()
erzwingt das Schließen der Datenbank unabhängig von allen anderen Threads, die Referenzen halten - also close()
selbst ist nicht einfach die Rückgängigmachung des Abgleichs getWriteableDatabase
aber zwangsweise schließen 何れも offene Anfragen. In den meisten Fällen ist dies kein Problem, da der Code einfädig ist, aber in Fällen mit mehreren Fäden besteht immer die Möglichkeit, dass das Öffnen und Schließen nicht synchron ist.
Nachdem ich an anderer Stelle Kommentare gelesen habe, die erklären, dass die SqLiteDatabaseHelper-Code-Instanz zählt, ist der einzige Zeitpunkt, an dem Sie eine Schließung wünschen, die Situation, in der Sie eine Sicherungskopie erstellen möchten, und Sie möchten erzwingen, dass alle Verbindungen geschlossen werden und SqLite dazu zwingen, alle zwischengespeicherten Daten, die möglicherweise herumliegen, wegzuschreiben.
Obwohl es sich wie eine gute Idee anhört, zu versuchen, die VM kontrolliert zu schließen, ist es in der Realität so, dass Android sich das Recht vorbehält, die VM zu löschen, so dass jedes Schließen das Risiko reduziert, dass zwischengespeicherte Updates nicht geschrieben werden, aber es kann nicht garantiert werden, wenn das Gerät gestresst ist, und wenn Sie Ihre Cursor und Verweise auf Datenbanken (die keine statischen Mitglieder sein sollten) korrekt freigegeben haben, dann wird der Helfer die Datenbank sowieso geschlossen haben.
Meiner Meinung nach ist der Ansatz also folgender:
Verwenden Sie getWriteableDatabase zum Öffnen aus einer Singleton-Verschalung (ich habe eine abgeleitete Anwendungsklasse verwendet, um den Anwendungskontext aus einer statischen Klasse bereitzustellen, damit kein Kontext erforderlich ist).
Rufen Sie niemals direkt in der Nähe an.
Speichern Sie die resultierende Datenbank niemals in einem Objekt, das keinen offensichtlichen Anwendungsbereich hat, und verlassen Sie sich auf die Referenzzählung, um ein implizites close() auszulösen.
Wenn Sie auf Dateiebene arbeiten, bringen Sie alle Datenbankaktivitäten zum Stillstand und rufen Sie dann "close" auf, für den Fall, dass ein "Runaway Thread" auftritt.