Vantaggio dell’uso di Parcelable invece di serializzare l’object

Come ho capito, Bundle e Parcelable appartengono al modo in cui Android esegue la serializzazione. Viene utilizzato ad esempio per passare i dati tra le attività. Ma mi chiedo, se ci sono dei vantaggi nell’usare Parcelable invece della serializzazione classica in caso di salvataggio dello stato dei miei oggetti di business nella memoria interna, ad esempio? Sarà più semplice o più veloce del modo classico? Dove dovrei usare la serializzazione classica e dove usare meglio i bundle?

Da “Pro Android 2”

NOTA: la visualizzazione di Parcelable potrebbe aver triggersto la domanda, perché Android non utilizza il meccanismo di serializzazione Java incorporato? Risulta che il team di Android è giunto alla conclusione che la serializzazione in Java è troppo lenta per soddisfare i requisiti di comunicazione interprocesso di Android. Quindi il team ha costruito la soluzione Parcelable. L’approccio Parcelable richiede la serializzazione esplicita dei membri della class, ma alla fine si ottiene una serializzazione molto più veloce dei propri oggetti.

Inoltre, renditi conto che Android offre due meccanismi che ti consentono di passare i dati a un altro processo. Il primo è passare un bundle a un’attività utilizzando un intento e il secondo è passare un Parcelable a un servizio. Questi due meccanismi non sono intercambiabili e non dovrebbero essere confusi. Cioè, il Parcelable non è pensato per essere passato a un’attività. Se si desidera avviare un’attività e trasmetterne alcuni dati, utilizzare un pacchetto. Parcelable è pensato per essere utilizzato solo come parte di una definizione AIDL.

Serializable è comicamente lento su Android. Borderline inutile in molti casi, infatti.

Parcel e Parcelable sono Parcelable veloci, ma la sua documentazione dice che non è necessario utilizzarlo per la serializzazione generalizzata per lo storage, poiché l’implementazione varia a seconda delle versioni di Android (ovvero un aggiornamento del sistema operativo potrebbe interrompere un’app che si basava su di esso).

La soluzione migliore per il problema della serializzazione dei dati nell’archiviazione a una velocità ragionevole è quella di eseguire il rollover. Personalmente utilizzo una delle mie classi di utilità che ha un’interfaccia simile a Parcel e che può serializzare tutti i tipi standard in modo molto efficiente (a scapito della sicurezza del tipo). Ecco una versione ridotta di esso:

 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 ArrayList readPackageableList(Class clazz) throws IOException { int N = readInt(); if (N == -1) { return null; } ArrayList list = new ArrayList(); 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 void writePackageableList(ArrayList 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++; } } } 

Guarda quanto è veloce Parcelable di Serializable.


inserisci la descrizione dell'immagine qui

da PERCHÉ AMIAMO PARCELABILI


inserisci la descrizione dell'immagine qui

da Parcelable a Serializable

Se è necessaria la serializzazione, ad esempio per motivi di archiviazione, ma si desidera evitare la penalità di velocità di riflessione sostenuta dall’interfaccia Serializable , è necessario creare in modo esplicito il proprio protocollo di serializzazione con l’interfaccia Externalizable .

Se correttamente implementato, corrisponde alla velocità di Parcelable e tiene conto anche della compatibilità tra diverse versioni di Android e / o della piattaforma Java.

Questo articolo potrebbe chiarire anche le cose:

Qual è la differenza tra Serializable ed Externalizable in Java?

In un sidenote, è anche la tecnica di serializzazione più veloce in molti benchmark, battendo Kryo, Avro, Protocol Buffers e Jackson (json):

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

Sembra che al giorno d’oggi la differenza non sia così evidente, almeno non quando la gestisci tra le tue attività.

Secondo i test mostrati su questo sito , Parcelable è circa 10 volte più veloce sui nuovi dispositivi (come nexus 10), ed è circa 17 più veloce su quelli vecchi (come il desiderio Z)

quindi spetta a te decidere se ne vale la pena.

forse per classi relativamente piccole e semplici, Serializable va bene, e per il resto, dovresti usare Parcelable

Parcelable è principalmente correlato a IPC utilizzando l’infrastruttura di Binder , in cui i dati vengono passati come pacchetti .

Poiché Android si affida molto a Binder per la maggior parte, se non tutte, le attività IPC, ha senso implementare Parcelable nella maggior parte dei casi, e specialmente nel framework, perché consente di passare un object a un altro processo, se necessario. Rende gli oggetti “trasportabili”.

Ma se si dispone di un livello aziendale non specifico per Android che utilizza in modo estensivo serializzabili per salvare gli stati degli oggetti e deve solo memorizzarli nel file system, allora penso che la serializzazione sia valida. Permette di evitare il codice piastra caldaia Parcelable.

Basato su questo articolo http://www.mooproductions.org/node/6?page=5 Parcelable dovrebbe essere più veloce.

Non menzionato nell’articolo, è che non riesco a pensare che gli oggetti serializzabili funzioneranno in AIDL per i servizi remoti.

Uso solo GSON -> Serializza in stringa JSON -> Ripristina object da stringa JSON.

Inoltre Parcelable offre un’implementazione personalizzata in cui l’utente ha la possibilità di pacchettizzare ciascuno dei suoi oggetti sovrascrivendo writeToParcel (), Tuttavia la serializzazione non prevede questa implementazione personalizzata poiché il suo modo di passare i dati coinvolge l’API di riflessione JAVA.