Vorteil der Verwendung von Parcelable anstelle der Serialisierung von Objekten

Lesezeit: 9 Minuten

Vorteil der Verwendung von Parcelable anstelle der Serialisierung von Objekten
Wladimir Iwanow

Wie ich es verstehe, Bundle und Parcelable gehört zu der Art und Weise, wie Android die Serialisierung durchführt. Sie wird beispielsweise zum Übergeben von Daten zwischen Aktivitäten verwendet. Aber ich frage mich, ob es irgendwelche Vorteile bei der Verwendung gibt Parcelable statt klassischer Serialisierung zum Beispiel beim Speichern des Zustands meiner Geschäftsobjekte im internen Speicher? Geht es einfacher oder schneller als der klassische Weg? Wo sollte ich die klassische Serialisierung einsetzen und wo besser Bundles?

Vorteil der Verwendung von Parcelable anstelle der Serialisierung von Objekten
Rajath

Ab “Pro Android 2”

HINWEIS: Parcelable zu sehen, hat möglicherweise die Frage ausgelöst, warum Android nicht den integrierten Java-Serialisierungsmechanismus verwendet. Es stellte sich heraus, dass das Android-Team zu dem Schluss kam, dass die Serialisierung in Java viel zu langsam ist, um die Anforderungen von Android an die Kommunikation zwischen Prozessen zu erfüllen. Also baute das Team die Parcelable-Lösung. Der Parcelable-Ansatz erfordert, dass Sie die Mitglieder Ihrer Klasse explizit serialisieren, aber am Ende erhalten Sie eine viel schnellere Serialisierung Ihrer Objekte.

Beachten Sie auch, dass Android zwei Mechanismen bietet, mit denen Sie Daten an einen anderen Prozess übergeben können. Die erste besteht darin, ein Bundle mithilfe einer Absicht an eine Aktivität zu übergeben, und die zweite besteht darin, ein Parcelable an einen Dienst zu übergeben. Diese beiden Mechanismen sind nicht austauschbar und sollten nicht verwechselt werden. Das Parcelable soll also nicht an eine Aktivität übergeben werden. Wenn Sie eine Aktivität starten und ihr einige Daten übergeben möchten, verwenden Sie ein Bundle. Parcelable soll nur als Teil einer AIDL-Definition verwendet werden.

  • Professionelle Android 2 Anwendungsentwicklung von Reto Meier amazon.com/…

    – mparaz

    12. Juni 2012 um 3:03 Uhr


  • Der zweite Absatz ist nicht wahr, Sie können ein Parcelable als Parameter an eine Aktivität übergeben, die das Bündel verwendet …

    – Benutzer

    22. Juni 2012 um 19:46 Uhr

  • Wenn ich meine Objekte serialisiere, erstelle ich eine getBundle Methode, dann rufen Sie diese von auf writeToParcel als dest.writeBundle(getBundle()); und ich habe beide Optionen automatisch im Objekt verfügbar. Hier sind interessante Paketfunktionen für Live-Objekte aufgeführt: developer.android.com/reference/android/os/Parcel.html

    – mikebabcock

    26. September 2012 um 16:06 Uhr

  • @lxx: Ich habe mich gefragt, warum man ein parzellierbares Objekt durch Bündel an die Aktivität übergeben muss. IMO, wenn Sie dies tun, fügen Sie unnötigerweise eine weitere Serialisierungsebene hinzu und sonst nichts.

    – Erhebt euch

    28. November 2012 um 6:30 Uhr


  • Philippe Breault hat darüber einen schönen Artikel geschrieben und auch einen Leistungstest hinzugefügt. developerphil.com/parcelable-vs-serializable

    – WonderCsabo

    5. Juli 2013 um 16:35 Uhr

1647255192 614 Vorteil der Verwendung von Parcelable anstelle der Serialisierung von Objekten
Ruben Scratton

Serializable ist komisch langsam auf Android. In vielen Fällen sogar grenzwertig nutzlos.

Parcel und Parcelable sind fantastisch schnell, aber es ist Dokumentation sagt, dass Sie es nicht für die Allzweck-Serialisierung zum Speicher verwenden dürfen, da die Implementierung mit verschiedenen Android-Versionen variiert (dh ein Betriebssystem-Update könnte eine App beschädigen, die darauf angewiesen ist).

Die beste Lösung für das Problem, Daten mit angemessener Geschwindigkeit in den Speicher zu serialisieren, besteht darin, Ihre eigene zu erstellen. Ich persönlich verwende eine meiner eigenen Utility-Klassen, die eine ähnliche Schnittstelle zu hat Parcel und die alle Standardtypen sehr effizient serialisieren kann (auf Kosten der Typsicherheit). Hier ist eine gekürzte Version davon:

public interface Packageable {
    public void readFromPackage(PackageInputStream in)  throws IOException ;
    public void writeToPackage(PackageOutputStream out)  throws IOException ; 
}


public final class PackageInputStream {

    private DataInputStream input;

    public PackageInputStream(InputStream in) {
        input = new DataInputStream(new BufferedInputStream(in));
    }

    public void close() throws IOException {
        if (input != null) {
            input.close();
            input = null;
        }       
    }

    // Primitives
    public final int readInt() throws IOException {
        return input.readInt();
    }
    public final long readLong() throws IOException {
        return input.readLong();
    }
    public final long[] readLongArray() throws IOException {
        int c = input.readInt();
        if (c == -1) {
            return null;
        }
        long[] a = new long[c];
        for (int i=0 ; i<c ; i++) {
            a[i] = input.readLong();
        }
        return a;
    }

...

    public final String readString()  throws IOException {
        return input.readUTF();
    }
    public final <T extends Packageable> ArrayList<T> readPackageableList(Class<T> clazz) throws IOException {
        int N = readInt();
        if (N == -1) {
            return null;
        }
        ArrayList<T> list = new ArrayList<T>();
        while (N>0) {
            try {
                T item = (T) clazz.newInstance();
                item.readFromPackage(this);
                list.add(item);
            } catch (InstantiationException e) {
                e.printStackTrace();
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            }
            N--;
        }
        return list;
    }

}



public final class PackageOutputStream {

    private DataOutputStream output;

    public PackageOutputStream(OutputStream out) {
        output = new DataOutputStream(new BufferedOutputStream(out));
    }

    public void close() throws IOException {
        if (output != null) {
            output.close();
            output = null;
        }
    }

    // Primitives
    public final void writeInt(int val) throws IOException {
        output.writeInt(val);
    }
    public final void writeLong(long val) throws IOException {
        output.writeLong(val);
    }
    public final void writeLongArray(long[] val) throws IOException {
        if (val == null) {
            writeInt(-1);
            return;
        }
        writeInt(val.length);
        for (int i=0 ; i<val.length ; i++) {
            output.writeLong(val[i]);
        }
    }

    public final void writeFloat(float val) throws IOException {
        output.writeFloat(val);
    }
    public final void writeDouble(double val) throws IOException {
        output.writeDouble(val);
    }
    public final void writeString(String val) throws IOException {
        if (val == null) {
            output.writeUTF("");
            return;
        }
        output.writeUTF(val);
    }

    public final <T extends Packageable> void writePackageableList(ArrayList<T> val) throws IOException {
        if (val == null) {
            writeInt(-1);
            return;
        }
        int N = val.size();
        int i=0;
        writeInt(N);
        while (i < N) {
            Packageable item = val.get(i);
            item.writeToPackage(this);
            i++;
        }
    }

}

  • Was ist der Unterschied zwischen der Verwendung dieser benutzerdefinierten Klasse von Ihnen und der Implementierung der Externalizable-Schnittstelle und der gleichen Vorgehensweise?

    – Karottenmann42

    29. Juni 2012 um 12:41 Uhr

  • Bundle serialisiert auch die Feldnamen … es ist nicht für Tausende von Objekten geeignet.

    – Ruben Scratton

    27. September 2012 um 8:08 Uhr


  • Tut mir leid, ich erfinde noch einen weiteren Serializer saugt – jetzt gibt es nur noch ein weiteres “Parcelable” zu erledigen. Es gibt eine große Auswahl mit einer Bibliothek (der Unterschied besteht darin, dass die Bibliothek überprüft, getestet und ein Format verwendet, das andere verwenden): ProtocolBuffers, JSON, XML usw. Es ist eine Schande, dass die Android-Bibliothek in dieser Hinsicht wirklich scheiße ist .

    Benutzer166390

    15. Januar 2013 um 6:39 Uhr


  • Ich glaube nicht, dass der Eröffnungssatz mehr wahr ist (5 Jahre nachdem er gemacht wurde). Ich verwende die Java-Serialisierung seit langem ohne Probleme. Einige möglicherweise interessante Dinge zu diesem Thema finden Sie in einem Blogbeitrag, den ich gerade geschrieben habe. nemanjakovacevic.net/blog/english/2015/03/24/…

    – Nemanja Kovacevic

    25. März 2015 um 0:42 Uhr

  • Ja, es ist nicht mehr so ​​ein Problem. Ich habe seit mehreren Jahren nichts anderes als Serializable (mit optimierten readObject/writeObject-Implementierungen) verwendet. Tatsächlich habe ich mir erst vor ein paar Tagen einen Hex-Dump einiger serialisierter Objekte angesehen und war zufrieden, dass es nicht zu verschwenderisch war.

    – Ruben Scratton

    25. März 2015 um 13:03 Uhr

Sehen Sie, wie schnell Paketfähig ist als serialisierbar.


Geben Sie hier die Bildbeschreibung ein

von WARUM WIR PAKETBAR LIEBEN


Geben Sie hier die Bildbeschreibung ein

von Paketfähig vs. serialisierbar

Vorteil der Verwendung von Parcelable anstelle der Serialisierung von Objekten
Weißbraue

Wenn Sie eine Serialisierung z. B. für Speicherzwecke benötigen, aber die Geschwindigkeitseinbußen durch Reflektion vermeiden möchten, die durch die entstehen Serialisierbar Schnittstelle sollten Sie explizit Ihr eigenes Serialisierungsprotokoll mit der erstellen Externalisierbar Schnittstelle.

Bei richtiger Implementierung entspricht dies der Geschwindigkeit von Parcelable und trägt auch zur Kompatibilität zwischen verschiedenen Versionen von Android und/oder der Java-Plattform bei.

Auch dieser Artikel könnte Klarheit schaffen:

Was ist der Unterschied zwischen Serialisierbar und Externalisierbar in Java?

Nebenbei bemerkt ist es auch die schnellste Serialisierungstechnik in vielen Benchmarks und schlägt Kryo, Avro, Protocol Buffers und Jackson (json):

http://code.google.com/p/thrift-protobuf-compare/wiki/Benchmarking

Es scheint, dass der Unterschied heutzutage nicht mehr so ​​​​bemerkbar ist, zumindest nicht, wenn Sie es zwischen Ihren eigenen Aktivitäten ausführen.

Gemäß Tests auf gezeigt Diese Internetseite Parcelable ist auf den neuesten Geräten (wie Nexus 10) etwa 10-mal schneller und auf alten Geräten (wie Desire Z) etwa 17-mal schneller.

ob es sich lohnt, musst du also selbst entscheiden.

Vielleicht ist Serializable für relativ kleine und einfache Klassen in Ordnung, und für den Rest sollten Sie Parcelable verwenden

  • Ich denke, Sie haben Recht, wenn Sie sagen, dass die Differenz schrumpft. Ich habe jedoch herausgefunden, dass die Verwendung von serializable in Bezug auf die Größe des gemarshallten Byte-Arrays viel effizienter sein kann und dass dies dazu beitragen kann, TransactionTooLargeException zu vermeiden. Ich würde gerne Ihre Kommentare zu diesem (meinen) Blogbeitrag hören nemanjakovacevic.net/blog/english/2015/03/24/…

    – Nemanja Kovacevic

    25. März 2015 um 1:09 Uhr

  • Nun, Sie könnten das riesige speicherverbrauchende Objekt einfach in eine statische Variable einfügen und es direkt beim Abrufen auf null setzen (z. B. bei onCreate). Der Nachteil ist, dass es keine Multi-Prozesse unterstützt und es ein bisschen schmutzig ist, dies zu tun. Frage mich, ob das der Fall ist, wenn Sie eine große Bitmap übergeben möchten.

    – Android-Entwickler

    25. März 2015 um 6:22 Uhr


1647255194 670 Vorteil der Verwendung von Parcelable anstelle der Serialisierung von Objekten
Olivierg

Parcelable bezieht sich hauptsächlich auf IPC unter Verwendung von Bindemittel Infrastruktur, wo Daten weitergegeben werden Pakete.

Da Android für die meisten, wenn nicht alle IPC-Aufgaben stark auf Binder angewiesen ist, ist es an den meisten Stellen sinnvoll, Parcelable zu implementieren, insbesondere im Framework, da es die Übergabe eines Objekts an einen anderen Prozess ermöglicht, wenn Sie dies benötigen. Es macht Gegenstände „transportierbar“.

Aber wenn Sie eine nicht Android-spezifische Business-Schicht haben, die serialisierbare Objekte ausgiebig zum Speichern von Objektzuständen verwendet und sie nur im Dateisystem speichern muss, dann denke ich, dass serialisierbar ist. Es ermöglicht, den Boilerplate-Code Parcelable zu vermeiden.

  • Ich denke, Sie haben Recht, wenn Sie sagen, dass die Differenz schrumpft. Ich habe jedoch herausgefunden, dass die Verwendung von serializable in Bezug auf die Größe des gemarshallten Byte-Arrays viel effizienter sein kann und dass dies dazu beitragen kann, TransactionTooLargeException zu vermeiden. Ich würde gerne Ihre Kommentare zu diesem (meinen) Blogbeitrag hören nemanjakovacevic.net/blog/english/2015/03/24/…

    – Nemanja Kovacevic

    25. März 2015 um 1:09 Uhr

  • Nun, Sie könnten das riesige speicherverbrauchende Objekt einfach in eine statische Variable einfügen und es direkt beim Abrufen auf null setzen (z. B. bei onCreate). Der Nachteil ist, dass es keine Multi-Prozesse unterstützt und es ein bisschen schmutzig ist, dies zu tun. Frage mich, ob das der Fall ist, wenn Sie eine große Bitmap übergeben möchten.

    – Android-Entwickler

    25. März 2015 um 6:22 Uhr


1647255195 342 Vorteil der Verwendung von Parcelable anstelle der Serialisierung von Objekten
Mike dg

Basierend auf diesem Artikel http://www.mooproductions.org/node/6?page=5
Paketfähig sollte schneller sein.

Nicht erwähnt in dem Artikel ist, dass ich nicht glaube, dass serialisierbare Objekte in AIDL für Remote-Dienste funktionieren werden.

1001200cookie-checkVorteil der Verwendung von Parcelable anstelle der Serialisierung von Objekten

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy