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 s'il est avantageux d'utiliser Parcelable
au lieu de la sérialisation classique en cas de sauvegarde de l'état de mes objets métier 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?
Réponses
Trop de publicités?De "Pro Android 2"
NOTE: Voir Parcelable qui pourrait avoir déclenché la question, pourquoi est Android pas à l'aide de la built-in Java mécanisme de sérialisation? Il s'avère que le Android équipe est venu à la conclusion que la sérialisation en Java est beaucoup trop lente pour satisfaire Android interprocess communication les exigences. Ainsi, l'équipe a construit le Parcelable solution. L' Parcelable approche nécessite que vous avez explicitement sérialiser les membres de votre classe, mais à la fin, vous obtenez un beaucoup plus rapide la sérialisation des objets.
Aussi se rendre compte que Android fournit deux mécanismes qui vous permettent de passer des données à un autre processus. La première est de faire passer un faisceau pour une activité à l'aide d'une intention, et la deuxième est de faire passer un Parcelable à un service. Ces deux mécanismes ne sont pas interchangeables et ne doit pas être confus. Qui est, le Parcelable n'est pas destiné à être transmis à un de l'activité. Si vous souhaitez démarrer d'une activité et de transmettre certaines données, l'utilisation d'un bundle. Parcelable est destinée à être utilisées uniquement dans le cadre de un AIDL définition.
Serializable
est comique, c'est lent sur Android. La limite de l'inutile dans de nombreux cas, en fait.
Parcel
et Parcelable
sont incroyablement rapide, mais sa documentation indique que vous ne devez pas l'utiliser pour la sérialisation de stockage, depuis la mise en œuvre varie avec les différentes versions d'Android (c'est à dire une mise à jour OS pourrait se casser une application qui s'appuie sur elle).
La meilleure solution pour le problème de sérialisation de données pour le stockage à une vitesse raisonnable est de faire rouler votre propre. Personnellement, j'utilise un de mes propres classes utilitaires qui possède une interface similaire à l' Parcel
et qui peut sérialiser tous les types standards de manière très efficace (au détriment de la sécurité de type). Voici une version abrégée de celui-ci :
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++;
}
}
}
Si vous avez besoin de sérialisation pour dire des fins de stockage mais qui veulent éviter la pénalité sur la vitesse de réflexion engagés par le Serializable interface explicite de créer votre propre sérialisation protocole avec la Externalizable interface.
Lorsqu'il est correctement mis en œuvre correspond à la vitesse de Parcelable et tient également compte de la compatibilité entre les différentes versions d'Android et/ou de la plate-forme Java.
Cet article peut effacer les choses ainsi:
Quelle est la différence entre Serializable et Externalizable en Java?
Sur une note, il est aussi le plus rapide de la sérialisation technique dans de nombreux repères, en battant Kryo, Avro, Protocol Buffers et Jackson (json):
http://code.google.com/p/thrift-protobuf-compare/wiki/Benchmarking
Il semble que de nos jours, la différence n'est pas si noticeble, au moins pas lorsque vous l'exécutez entre vos propres activités.
Selon les tests indiqués sur ce site web , Parcelable est environ 10 fois plus rapide sur les appareils les plus récents (comme la nexus 10), et est d'environ 17 plus vite sur les anciens (comme le désir Z)
donc, c'est à vous de décider si c'valeurs.
peut-être que pour un nombre relativement petits et des classes simples, Serializable est très bien, et pour le reste, vous devez utiliser Parcelable
Parcelable est principalement liée à la CIB à l'aide de la Reliure de l'infrastructure, où les données sont transmises en tant que Colis.
Depuis Android s'appuie beaucoup sur le Classeur pour la plupart, si pas tous, IPC tâches, il est logique de mettre en œuvre Parcelable dans la plupart des endroits, et notamment dans le cadre, car il permet de passer d'un objet à un autre processus si vous avez besoin que. Il rend les objets "transportable".
Mais si vous n'avez pas un Android, de la couche de gestion qui utilisent intensivement serializables pour enregistrer l'objet unis, et seulement besoin de les stocker sur le système de fichiers, puis je pense que serializable est fine. Il permet d'éviter la Parcelable chaudière-plaque de code.