Realm hat dieses Problem nicht mehr.
meine Lösung zu dem Zeitpunkt als Referenz war:
Dank mir beeender in die richtige Richtung für den Hinweis und die Verknüpfung dieser PR https://github.com/realm/realm-java/pull/1297
Ausgabe
Wenn es eine anhängige Realm Transaktion Jeder Aufruf von Realm.getInstance
in einem anderen Thread wird blockiert, bis die ausstehende Transaktion festgeschrieben oder abgebrochen wurde.
In meinem Fall habe ich einen IntentService, der mein Realm mit vorhandenen Benutzerdaten füllt, während ich versuche, alle aktuellen Daten anzuzeigen, indem ich Realm auf dem UI-Thread abfrage. Obwohl die Abfragen einfach sind und normalerweise keine Probleme verursachen, wird der Aufruf von Realm.getInstance
blockiert, wenn eine ausstehende Transaktion im IntentService vorhanden ist. Dadurch wird der UI-Thread blockiert und möglicherweise ein ANR verursacht.
Mein erster Versuch einer Lösung war, den PR-Zweig von Beeender zu ziehen und ein Glas zu erstellen. Ich glaube, dieser Fix brachte mich einen Schritt weiter und erlaubte die Erstellung der Realm-Instanz ohne Blockierung, aber der UI-Thread wurde immer noch von kleinen Transaktionen blockiert, die ich auf dem UI-Thread ausführen wollte.
Lösung
Die Lösung I umfasst mehrere Schritte umgesetzt:
- erstellen doppelte Objekte für alle meine Modelle. Die Duplikate erweitern RealmObject nicht, da RealmObjects nicht über Threads hinweg verwendet werden kann.
- Alle Zugriffe auf Realm auf Hintergrundthreads verschieben. Grundsätzlich habe ich meine Abfragen in AsyncTasks eingeschlossen und Listener hinzugefügt, die die Nicht-RealmObject-Version des Modells zurückgeben.
- Machen Sie mehr kleine Transaktionen als weniger große Transaktionen. Wo ich zuvor auf beiden Seiten einer Schleife, die viele neue RealmObjects erzeugt hat, Transaktionen gestartet und festgeschrieben habe, beginne ich jetzt und übertrage die Transaktion pro Objekt.Der Zweck davon ist, die gesamte ununterbrochene Zeit zu reduzieren, in der sich Realm in einem offenen Transaktionszustand befindet, so dass meine Abfragen, die Daten für die UI bereitstellen, abgeschlossen werden können, ohne dass sie so lange warten müssen.
Fazit
Ich war anfangs zögerlich Realm zu verwenden, weil es nach wie vor sowie die Einschränkung in der Beta ist, dass RealmObjects nicht über Threads verwendet werden. Nach einigen Tests war ich zuversichtlich, dass ich einfache Abfragen auf dem UI-Thread ohne Problem durchführen konnte (immer noch mit einem schlechten Gefühl in meinem Bauch.)
Insgesamt ist Realm ein großartiges Projekt, das man im Auge behalten muss, aber ich habe das Gefühl ist nicht bereit für große kommerzielle Projekte. Die Verwendung von Realm für dieses Projekt hat möglicherweise im Vorfeld etwas Zeit gespart, aber es hat viele unzufriedene Kunden und ein schwierig zu diagnostizierendes Problem gekostet.
* Bearbeiten: Abklären Problem.
Es scheint, Sie haben eine Schreib-Transaktion, die nicht geschlossen ist. Dies könnte den Realm blockieren, um eine neue Instanz zu öffnen. Überprüfen Sie diese PR https://github.com/realm/realm-java/pull/1297. Wenn dies der Fall ist, schlage ich vor, dass Sie Ihre Transaktion ordnungsgemäß schließen, anstatt auf die Korrektur zu warten, da die Schreibtransaktion sowieso geschlossen werden muss. – beeender
@beeendeder Wenn ich also eine Transaktion in einem Worker-Thread beginne und versuche, eine neue Realm-Instanz im Benutzeroberflächenthread zu öffnen, bevor die Worker-Thread-Transaktion festgeschrieben wird, wird der UI-Thread blockiert und wartet auf die Transaktion. – MichaelAnDev
Gerade jetzt, ja. Obwohl ich nicht denke, dass es das richtige Verhalten ist, könnte es einige Gründe für das aktuelle Verhalten geben, die mir nicht bekannt sind. Wenn nun eine Realm-Instanz in einem Thread erstellt wird und noch keine Instanz im Thread geöffnet ist, wird createAndValidate aufgerufen und möglicherweise durch eine Transaktion in anderen Threads blockiert. Wenn bereits eine geöffnete Instanz im Thread vorhanden ist, wird eine Referenz ohne Erstellung zurückgegeben. – beeender