Gute Alternativen, um einen komplexen Objektbaum zwischen Aktivitäten in Android zu teilen?

8

Dies ist eine Frage, die ich jetzt für ein paar verschiedene Apps hatte, die ich erstellt habe, und ich bin noch immer mit einer der Lösungen zufrieden, die ich mir ausgedacht habe. Ich dachte, ich würde es der Community zeigen, um andere Lösungen zu sehen.

Nehmen wir an, Sie haben eine Aktivität, die einen komplexen Baum von Daten herunterlädt (in diesem Fall über json, aber es könnte alles sein), entfernt diese Daten in eine Menge von Java-Objekten (in diesem Fall mit gson, könnte aber auch wieder) Was auch immer), dann erzeugt zusätzliche Aktivitäten, um verschiedene Teile dieser Daten zu sehen. Es könnte eine Aktivität geben, um Trips in Ihrer Antwort anzuzeigen, und eine andere, um Flüge in diesen Trips anzuzeigen, und vielleicht auch eine andere, um Passagiere dieser Flüge zu sehen.

Meine anfängliche Implementierung dieser App bestand darin, alle Trips in der ersten Aktivität abzugruppieren und sie dann als Wert (als Extra in der Absicht) an TripActivity zu übergeben. Die TripActivity übergibt dann einzelne Flüge an die FlightActivity und so weiter.

Das Problem dabei ist, dass es eine merkliche Pause zwischen den Aktivitäten gibt, während die App die Daten serialisiert und deserialisiert. Wir sprechen mehrere Sekunden. Die Pause ist ziemlich auffällig, wenn mein Baum Serialization oder Parcelable verwendet, um Daten herumzugeben. Die anfänglichen Leistungstests mit google's Parcelable zeigen stattdessen eine ca. 30% ige Beschleunigung gegenüber der Serialisierung, aber Parcelable ist schwer zu handhaben und scheint keine zirkulären Objektreferenzen zu behandeln, wie die Serialisierung, und außerdem pausiert es für fast genauso viele Sekunden. also habe ich dieses Experiment auf den Backburner gelegt, während ich andere Dinge versuche.

Also habe ich versucht, den Baum von Objekten direkt in die Application-Klasse zu verschieben. Bei jeder Aktivität wird der Baum bei Bedarf direkt aus der App abgerufen. Dies macht die Leistung ziemlich bissig, aber die Behandlung von Eckenfällen wie unerwarteten Aktivitätsstart / -stopps (entweder aufgrund von Aktivitätsabstürzen oder weil die Aktivität vorübergehend geschlossen wurde, um mehr Speicher zur Verfügung zu stellen, oder was auch immer, ist schwierig). Vielleicht ist es nicht mehr als die Implementierung von onSaveInstanceState() , ich bin nicht sicher, aber die Lösung scheint ein bisschen hacky, also habe ich noch nicht weiter untersucht.

Also habe ich auf der Suche nach einer Lösung, die weniger zusammengewürfelt ist, versucht, einen eigenen ContentProvider zu erstellen, um meine Objekte zu speichern und abzurufen. Da ContentProvider so konfiguriert werden können, dass sie prozessintern mit multiprocess=true ausgeführt werden, dachte ich, dass dies eine hervorragende Möglichkeit wäre, Serialisierungskosten zu vermeiden, während etwas "Standard" als das Speichern von Daten im Application-Objekt ausgeführt wird. ContentProvider waren jedoch offensichtlich nicht dazu gedacht, beliebige Objekttypen zurückzugeben - sie unterstützen nur Typen wie Zahlen, Strings, Boolesche Werte usw. Es scheint, als könnte ich eine beliebige Datei mit ContentResolver.getContentProviderClient().getLocalContentProvider() speichern und direkt auf meine benutzerdefinierte Klasse zugreifen. aber ich bin mir nicht sicher, dass das weniger hacky ist als das Speichern von Daten im Application-Objekt.

Sicher muss jemand eine gute Lösung für dieses Problem haben. Was mache ich falsch?

    
emmby 07.11.2009, 20:27
quelle

3 Antworten

3

Zusätzlich zur Lösung von fiXedd wird ein lokaler Dienst verwendet. Den Dienst "besitzen" die Objekte, wobei Aktivitäten Service-APIs aufrufen, um zu erhalten, was immer sie benötigt. Der Dienst kann auch für das Abrufen und Analysieren der Daten verantwortlich sein, indem er dieses logische Bit kapselt.

Das Objekt Application ist das "rothaarige Step-Kind" von Android-Komponenten. Mitglieder des Android-Kernteams haben sich gegen die Praxis gewehrt, benutzerdefinierte Application -Unterklassen zu erstellen, obwohl sie sicherlich von der API unterstützt werden. Nachdem ich eine ADC2 200-Anwendung entwickelt habe, die eine benutzerdefinierte Application -Unterklasse nutzt, kann ich sagen, dass ich auch in meinem Fall mit einem Dienst hätte arbeiten sollen. Lebe und lerne ...

Wenn Sie das lokale Bindungsmuster verwenden, wird Ihr Dienst automatisch erstellt und bei Bedarf gelöscht, sodass Sie sich keine Gedanken darüber machen müssen. Und per Definition läuft ein lokaler Service im selben Prozess / VM wie Ihre Aktivitäten, so dass Sie sich keine Gedanken über das Marshalling von Overhead machen müssen, wie Sie es im Szenario ContentProvider tun würden.

    
CommonsWare 08.11.2009, 01:20
quelle
1

Die Art, wie ich das in einer meiner Apps bearbeite, ist das Herunterladen der Daten und dann das Verschieben in eine Datenbank. Auf diese Weise muss ich nicht all diese Objekte herumtragen (welche, IIRC, nur etwa 1kb für die Objekt-Instanziierung essen) und ich kann einfach nur die Daten ziehen, die ich brauche. Ich weiß nicht, ob das für dich funktioniert, aber es funktionierte für meinen Anwendungsfall.

    
Jeremy Logan 08.11.2009 00:31
quelle
0

Ein anderer Ansatz wäre, die Datenobjekte in einer gemeinsamen Voreinstellungsdatei zu speichern. So haben wir eine unserer Apps implementiert, aber ich mochte diesen Ansatz nicht, weil er zu langsam erscheint.

Es ist ein schlechtes Programmierverfahren, aber der schnellste Weg könnte darin bestehen, einfach einen Dienst zu verwenden, um die Daten zu parsen und die Daten in einer statischen Klasse zu speichern, die Sie für den Rest der Lebensdauer der App verwenden können.

    
Lou Morda 18.12.2012 17:10
quelle

Tags und Links