Serialisierung 101 mit JSON in Android

Serialisierung 101 mit JSON in Android

JSON ist ein wunderbares Datenformat. Es ist leicht, einfach zu bedienen und hat eine einfache Struktur, die eng Daten übereinstimmen Typen und Strukturen in jedem voll funktionsfähigen Programmiersprache (Implementierungen existiert mehr Dutzende Programmiersprachen). Wenn ich bin nicht libs11n für die Serialisierung mit benutze ich JSON.

Dieser Beitrag ist über die ersten Schritte mit JSON-basierter Serialisierung in Java. Was bedeutet „Serialisierung“ bedeuten? Im Grunde bedeutet es „Speicher und Laden“, sondern auf einer abstrakteren Ebene als einfach zu / von Dateien. Serialisierung hat viele Anwendungen, z.B. Übergabe von Daten zwischen den Aktivitäten oder Dienste (z.B. GDrive oder die Zwischenablage). Warum Einbau-Serialisierung von Java nicht? Es ist in Ordnung für RPC und andere Formen von transienten Daten, aber das Format ist nicht über Anrufungen bleiben stabil garantiert und ist daher völlig ungeeignet für die Verwendung bei der Speicherung von Daten Anwendung längerfristigen.

Forewarning. der JSON-API in diesem Artikel verwendete auf der gleiche json.org API in Android gebaut basiert (sie haben eine abgespeckte Version), aber diese Kopie vom Original geringfügig modifiziert ist, (i gegabelt es vor ein paar Jahren von json. org für die Arbeit in keinem Zusammenhang mit Android). d.h. verhält es sich etwas anders als die Android JSON API. Der bemerkenswerteste Unterschied ist, dass nach der API in mehreren Anwendungen unter Verwendung von i die geprüfte JSONException zu einer ungeprüften Ausnahme geändert. Dies vereinfacht die Verwendung für die Mehrzahl der Fälle (wo wir nur mit internen Daten arbeiten, die „nicht versagen können,“ wenn wir unsere Arbeit richtig gemacht haben), während noch der Client erlaubt explizit Fehler zu fangen, wenn, zum Beispiel sie versuchen, serialize Benutzer bereitgestellte Daten de (die wir vorher nicht wissen, wie JSON validieren). Es hat auch einige (kleine) Unterstützung für Java 6 Generics, wo die json.org API nicht (sie wollen ihre zu älteren JVMs tragbar sein).

Lassen Sie uns ein einfaches Interface für Klassen definieren, die serializable über JSON sein sollen. Wir brauchen nicht, dies zu tun, und ich dies oft nicht tun, wenn Behälter oder einfache Typen wie Instanzen des Paint Klasse serialisiert. Dennoch ist es eine nette Formalität wird zu haben und oft nützlicher als ein Projekt wächst.

Als Faustregel gilt, wenn i app-internen Daten serialisiert, neige ich dazu, ziemlich locker zu sein und die „Verwendung vorhandene Werte als Standardwert“ Ansatz, und wenn die Deserialisierung eines kleinen / unwichtigen Teil der Daten fehlschlägt, dann neige ich dazu, das ignorieren Fehler und mit einem Standard wiederherstellen oder den aktuellen Wert recyceln. Wenn vom Benutzer bereitgestellte Daten Deserialisieren müssen wir in der Regel ein bisschen vorsichtiger sein. Da Android einer App private Dateien vor Manipulationen schützt, ist es „normal ziemlich sicher davon ausgehen“ (berühmte letzte Worte), dass die Daten eine App spart sich richtig deserialisiert wird.

JSON-Liebhaber können feststellen, dass die Schnittstelle nicht berücksichtigt Array-Daten. Das ist wahr - ich verwende Arrays als Top-Level / root JSON-Objekte nie. Arrays werden durch Zugabe sie als JSONObject Eigenschaften, unter Verwendung von JSONArray als Wert Typ indirekt unterstützt.

Wir brauchen eine Klasse serialisierbar zu machen. Anstatt eine für Demonstrationszwecke ersinnen, werden wir ein wiederverwenden, die einen Teil von HGR ist. HGR größten Stücke von serialisierten Daten sind android.graphics.Paint Objekte (sie machen wahrscheinlich 90% der Speicheranforderungen). Mit nur ein wenig Mühe, können wir sie über JSON speichern und laden ...

Beachten Sie, dass diese Klasse nicht die JSONable Schnittstelle nicht implementieren wir so sorgfältig ausgearbeitet! Warum nicht? Ein Unfall der Evolution. Wenn kleine Objekte von einigen eingebauten Typ Serialisierung verwenden i normalerweise statische Helfer eher als eine Klasse zu implementieren, die einfach den ursprünglichen Griff für die Zwecke einer Serialisierung oder Deserialisierung Anruf wickelt. Das heißt, die Schnittstelle dieser Klasse abstrakt identisch mit der JSONable Schnittstelle ist, mit der Ausnahme, daß die „this“ Objekt als ersten Parameter übergeben wird.

(Trivia: der obige Code fehlt die Teile, welche die Farbe Objekte Schriftbild Mitglied Griff Das bleibt als Übung für den Leser (es gibt mehrere gültige Ansätze)..)

Normalerweise (aber nicht immer) brauchen wir Daten zu speichern, bevor wir es laden können (wenn auch manchmal eingelesenen Daten wird durch unsere App nicht gespeichert). Also hier ist, wie wir es tun:

Das ist alles dazu. Wir können ihn jetzt noch retten überall ist es legal, eine Zeichenfolge zu speichern.

Dies ist ebenso einfach und kann durch Zugabe von typspezifischen Wrapper noch einfacher gemacht werden:

Auch das ist alles dort ist zu ihm. Beachten Sie, dass der JSONObject Konstruktor einen ungeprüften JSONException werfen kann, und es ist eine sehr gute Idee, zu versuchen / catch, die, vor allem, wenn vom Benutzer bereitgestellte Daten zu lesen. zu tun Anderenfalls kraft der Nähe der App so führen, es sei denn ein höherer Ebene Anrufer es fängt.

Sobald ein Typ serializable ist, ist es verwendbar in jedem Kontext, dass serializable Serialisierungsformat (in unserem Fall JSON) unterstützt. Was bedeutet das? Es bedeutet, dass wir jetzt tun können / serialisiert eine Karte oder eine Karte> Oder gleich esoterische Kombinationen, von / zu JSON mit gleicher Leichtigkeit. Es hilft, wenn die Typen eine gemeinsame Schnittstelle haben serialisiert werden, wie ein statischen Helfer wie die oben PaintSerializer Gegensatz gezeigt, weil wir dann generische Algorithmen, uns zu unterstützen schreiben können. Oft ist es sinnvoll, eine Utility-Klasse zu schaffen, die gemeinsame JSON-bezogene Funktionalität einpackt, z.B. Speichern und Laden von JSON zu / von App-Ressourcen / assets, Streams oder Dateien.

die neu initiierte helfen hier auf dem Weg, sind ein paar allgemeine Routinen ich meine app-private JSON für den Umgang mit Dateien hilfreich sein:

-- stephan beal

In Verbindung stehende Artikel