web-dev-qa-db-fra.com

Avantage d'utiliser Parcelable au lieu de sérialiser l'objet

Si je comprends bien, Bundle et Parcelable appartiennent à la manière dont Android effectue la sérialisation. Il est utilisé par exemple pour la transmission de données entre activités. Mais je me demande si l’utilisation de Parcelable au lieu de la sérialisation classique présente des avantages en cas de sauvegarde de l’état de mes objets d’entreprise dans la mémoire interne, par exemple? Sera-ce plus simple ou plus rapide que la méthode classique? Où devrais-je utiliser la sérialisation classique et où mieux utiliser les bundles?

95
Vladimir Ivanov

À partir de "Pro Android 2"

REMARQUE: Voir Parcelable a peut-être provoqué la question de savoir pourquoi Android n'utilise pas le fichier mécanisme de sérialisation Java intégré? Il se trouve que le L'équipe Android est arrivée à la conclusion que la sérialisation en Java est beaucoup trop lente pour satisfaire les besoins d'Android communication interprocessus exigences. L'équipe a donc créé la solution Parcelable. Le L’approche parcellaire nécessite que vous sérialisiez explicitement les membres de votre classe, mais finalement, vous obtenez un beaucoup plus rapide la sérialisation de vos objets. 

Sachez également qu'Android fournit deux mécanismes vous permettant de passer données à un autre processus. La première consiste à transmettre un ensemble à une activité à l'aide d'une intention, et le second est de passer un Colisable à un service. Ces deux mécanismes ne sont pas interchangeables et ne devrait pas être confus. C'est-à-dire que le colisable n'est pas destiné à être passé à un activité. Si vous voulez commencer une activité et lui transmettre des données, utilisez un paquet. Parcelable est destiné à être utilisé que dans le cadre de une définition AIDL.

100
rajath

Serializable est comiquement lent sur Android. La limite est inutile dans de nombreux cas en fait.

Parcel et Parcelable sont incroyablement rapides, mais sa documentation indique que vous ne devez pas l'utiliser pour la sérialisation à usage général pour le stockage, car la mise en œuvre varie selon les versions d'Android (une mise à jour du système d'exploitation pourrait endommager une application qui en dépend ).

La meilleure solution au problème de la sérialisation des données sur le stockage à une vitesse raisonnable consiste à rouler vous-même. J'utilise personnellement l'une de mes propres classes d'utilitaires qui possède une interface similaire à Parcel et qui permet de sérialiser tous les types standard de manière très efficace (au détriment de la sécurité du type). En voici une version abrégée:

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++;
        }
    }

}
22
Reuben Scratton

Voyez à quelle vitesse Parcelable est plus que Serializable.


 enter image description here

depuis POURQUOI WE LOVE PARCELABLE


 enter image description here

from Parcelable vs Serializable

11
phi

Si vous avez besoin de la sérialisation, par exemple pour le stockage, mais que vous souhaitez éviter la pénalité de réflexion due à l'interface Serializable, vous devez créer explicitement votre propre protocole de sérialisation avec l'interface Externalizable.

Lorsqu'il est correctement implémenté, il correspond à la vitesse de Parcelable et permet également la compatibilité entre différentes versions d'Android et/ou de la plate-forme Java.

Cet article pourrait éclaircir les choses aussi:

Quelle est la différence entre Serializable et Externalizable en Java?

Sur un sidenote, c’est aussi la technique de sérialisation la plus rapide dans de nombreux tests, battant Kryo, Avro, Protocol Buffers et Jackson (json):

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

10
whitebrow

Il semble qu’aujourd’hui, la différence ne soit pas aussi remarquable, du moins pas lorsque vous la dirigez entre vos propres activités.

Selon les tests présentés sur ce site Web , Parcelable est environ 10 fois plus rapide sur les appareils les plus récents (comme Nexus 10) et environ 17 fois plus vite sur les anciens (comme le désir Z).

c'est donc à vous de décider si cela en vaut la peine.

peut-être que pour les classes relativement petites et simples, Serializable convient, et pour le reste, vous devriez utiliser Parcelable

7
android developer

Parcelable est principalement lié à IPC à l'aide de l'infrastructure Binder , où les données sont transmises sous la forme Parcels .

Étant donné qu'Android s'appuie beaucoup sur Binder pour la plupart, sinon la totalité, des tâches IPC, il est logique d'implémenter Parcelable dans la plupart des endroits, et en particulier dans le cadre, car il permet de passer un objet à un autre processus si vous en avez besoin. . Cela rend les objets "transportables".

Mais si vous avez une couche de gestion non spécifique à Android qui utilise largement les sérialisables pour sauvegarder les états des objets et ne nécessite que de les stocker dans le système de fichiers, alors je pense que la sérialisation convient. Cela permet d'éviter le code de plaque de chaudière colisable.

4
olivierg

Basé sur cet article http://www.mooproductions.org/node/6?page=5 Parcelable devrait être plus rapide.

Non mentionné dans l'article, c'est que je ne pense pas que les objets sérialisables fonctionneront dans AIDL pour les services distants.

1
Mike dg

Je viens d'utiliser GSON -> Sérialiser sur JSON String -> Restaurer un objet à partir de JSON String. 

1
F.O.O

Parcelable propose également une implémentation personnalisée dans laquelle l'utilisateur a la possibilité de coliser chacun de ses objets en redéfinissant writeToParcel (). Cependant, la sérialisation ne fait pas de cette implémentation personnalisée car son mode de transmission de données implique l'API de réflexion Java.

0
Ajay Deepak