Die Android SDK-Dokumentation besagt, dass die startManagingCursor()
Methode verzerrt ist:
Diese Methode ist veraltet. Verwenden Sie stattdessen die neue CursorLoader-Klasse mit LoaderManager. Dies ist auch auf älteren Plattformen über das Android-Kompatibilitätspaket verfügbar. Mit dieser Methode kann die Aktivität den Lebenszyklus des angegebenen Cursors basierend auf dem Lebenszyklus der Aktivität für Sie verwalten. Das heißt, wenn die Aktivität gestoppt wird, wird automatisch disable () für den angegebenen Cursor aufgerufen, und wenn sie später neu gestartet wird, wird Requery () für Sie aufgerufen. Wenn die Aktivität zerstört wird, werden alle verwalteten Cursor automatisch geschlossen. Wenn Sie auf HONEYCOMB oder höher abzielen, sollten Sie stattdessen LoaderManager verwenden, der über getLoaderManager () verfügbar ist.
Also würde ich gerne verwenden CursorLoader
. Aber wie kann ich es mit benutzerdefinierten CursorAdapter
und ohne verwenden ContentProvider
, wenn ich URI im Konstruktor von benötige CursorLoader
?
Antworten:
Ich habe einen einfachen CursorLoader geschrieben , der keinen Inhaltsanbieter benötigt:
Es braucht nur die
AsyncTaskLoader
Klasse. Entweder die in Android 3.0 oder höher oder die, die mit dem Kompatibilitätspaket geliefert wird.Ich habe auch eine geschrieben,
ListLoader
die mit der kompatibelLoadManager
ist und zum Abrufen einer generischenjava.util.List
Sammlung verwendet wird.quelle
Schreiben Sie Ihren eigenen Loader, der Ihre Datenbankklasse anstelle eines Inhaltsanbieters verwendet. Am einfachsten ist es, die Quelle der
CursorLoader
Klasse aus der Kompatibilitätsbibliothek zu entnehmen und Anbieterabfragen durch Abfragen an Ihre eigene DB-Hilfsklasse zu ersetzen.quelle
CursorLoader
Nachkommen erstellt, um einen SQLite-Cursor zu verwalten. Ausgehend vom Konstruktor musste ich nur dieloadInBackground
Methode überschreiben , um die Anbieterabfrage durch meineDer SimpleCursorLoader ist eine einfache Lösung, unterstützt jedoch nicht die Aktualisierung des Loaders, wenn sich die Daten ändern. CommonsWare verfügt über eine Loaderex-Bibliothek, die einen SQLiteCursorLoader hinzufügt und die erneute Abfrage von Datenänderungen unterstützt.
https://github.com/commonsguy/cwac-loaderex
quelle
Eine dritte Möglichkeit wäre, einfach zu überschreiben
loadInBackground
:Dadurch wird auch sichergestellt, dass der Cursor erneut abgefragt wird, wenn sich die Datenbank ändert.
Einzige Einschränkung: Sie müssen einen anderen Beobachter definieren, da Google in seiner unendlichen Weisheit beschlossen hat, sein Paket privat zu machen. Wenn Sie die Klasse in dasselbe Paket wie die ursprüngliche (oder die kompatible) Klasse einfügen, können Sie tatsächlich den ursprünglichen Beobachter verwenden. Der Beobachter ist ein sehr leichtes Objekt und wird nirgendwo anders verwendet, daher macht dies keinen großen Unterschied.
quelle
loadInBackground()
, bevor Sie den Cursor zurückgeben, dasscursor.setNotificationUri(getContext().getContentResolver(), uri);
die URL möglicherweise nur aus zufälligen Zeichenfolgen bestehtUri.parse("content://query_slot1")
. Es scheint mir egal zu sein, ob der Uri wirklich existiert oder nicht. Und sobald ich die DB operiert habe. SaygetContentResolver().notifyChange(uri, null);
würde den Trick machen. Dann kann ich einige "Abfrage-Uri-Slot" in einer Contant-Datei für App mit einer geringen Anzahl von Abfragen erstellen. Ich teste das Einfügen des DB-Datensatzes zur Laufzeit und es scheint zu funktionieren, aber ich bezweifle immer noch, dass es eine gute Praxis ist. Irgendein Vorschlag?Die dritte von Timo Ohr vorgeschlagene Option liefert zusammen mit den Kommentaren von Yeung die einfachste Antwort (Occams Rasiermesser). Unten finden Sie ein Beispiel für eine vollständige Klasse, die für mich funktioniert. Es gibt zwei Regeln für die Verwendung dieser Klasse.
Stellen Sie sicher, dass Sie jedes Mal, wenn sich die zugrunde liegende Datenbank ändert (z. B. nach dem Einfügen oder Löschen), aufrufen
Dabei ist myUri dasselbe, das Sie von Ihrer Implementierung der Methode getContentUri () zurückgegeben haben.
Hier ist der Code für die Klasse, die ich verwendet habe:
quelle