Преимущество использования Parcelable вместо сериализации объекта

Насколько я понимаю, Bundle и Parcelable относятся к тому, как Android выполняет сериализацию. Он используется, например, для передачи данных между действиями. Но мне интересно, есть ли какие-либо преимущества при использовании Parcelable вместо классической сериализации в случае сохранения состояния моих бизнес-объектов во внутренней памяти, например? Будет ли это проще или быстрее классического? Где я должен использовать классическую сериализацию и где лучше использовать пакеты?

Solutions Collecting From Web of "Преимущество использования Parcelable вместо сериализации объекта"

От "Pro Android 2"

ПРИМЕЧАНИЕ. Увидев Parcelable, возможно, возник вопрос: почему Android не использует встроенный механизм сериализации Java? Оказывается, команда Android пришла к выводу, что сериализация в Java слишком медленна, чтобы удовлетворить требования Interprocess-communication от Android. Таким образом, команда построила решение Parcelable. Подход Parcelable требует, чтобы вы явно сериализовали членов вашего класса, но, в конце концов, вы получаете гораздо более быструю сериализацию своих объектов.

Также поймите, что Android предоставляет два механизма, которые позволяют передавать данные другому процессу. Первый заключается в том, чтобы передать пакет в действие с использованием намерения, а второй – передать Parcelable службе. Эти два механизма не взаимозаменяемы и их не следует путать. То есть, Parcelable не предназначен для передачи активности. Если вы хотите запустить мероприятие и передать ему некоторые данные, используйте пакет. Parcelable предназначен для использования только как часть определения AIDL.

Serializable на Android очень медленный. Граница бесполезна во многих случаях.

Parcel and Parcelable – это фантастически быстро, но в его документации говорится, что вы не должны использовать его для универсальной сериализации для хранения, поскольку реализация зависит от разных версий Android (то есть обновление ОС может сломать приложение, основанное на нем).

Лучшим решением проблемы сериализации данных для хранения на разумной скорости является сворачивание ваших собственных. Я лично использую один из моих собственных классов полезности, который имеет аналогичный интерфейс с Parcel и который может очень эффективно сериализовать все стандартные типы (за счет безопасности типа). Вот сокращенная версия:

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

Если вам нужна сериализация для целей хранения, но вы хотите избежать снижения скорости отражения, вызванного интерфейсом Serializable, вы должны явно создать свой собственный протокол сериализации с интерфейсом Externalizable .

При правильной реализации это соответствует скорости Parcelable, а также учитывает совместимость между различными версиями Android и / или платформы Java.

Эта статья также может прояснить ситуацию:

В чем разница между Serializable и Externalizable в Java?

В боковом объявлении он также является самым быстрым методом сериализации во многих тестах, избивая Kryo, Avro, Protocol Buffers и Jackson (json):

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

Посмотрите, насколько быстро Parcelable , чем Serializable.


Введите описание изображения здесь

От ПОЧЕМУ МЫ ЛЮБИМ ПАРТИИ


Введите описание изображения здесь

От Parcelable vs Serializable

Похоже, что в настоящее время разница не настолько заметна, по крайней мере, не тогда, когда вы запускаете ее между своими действиями.

Согласно испытаниям, показанным на этом веб-сайте , Parcelable примерно на 10 раз быстрее на новейших устройствах (например, nexus 10) и примерно на 17 быстрее по старым (например, желание Z)

Так что вам решать, стоит ли это.

Возможно, для относительно маленьких и простых классов, Serializable в порядке, а для остальных вам следует использовать Parcelable

Parcelable в основном связан с IPC, используя инфраструктуру Binder , где данные передаются как « Посылки» .

Поскольку Android много полагается на Binder для большинства, если не всех, задач IPC, имеет смысл реализовать Parcelable в большинстве мест, и особенно в рамках, поскольку он позволяет передать объект другому процессу, если вам это нужно. Это делает объекты «переносимыми».

Но если у вас есть бизнес-уровень, не зависящий от Android, который широко использует сериализуемые ресурсы для сохранения состояний объектов и должен хранить их только в файловой системе, тогда я думаю, что сериализуемое отлично. Это позволяет избежать кода котельной.

На основании этой статьи http://www.mooproductions.org/node/6?page=5 Parcelable должен быть быстрее.

Не упоминается в статье, что я не считаю, что сериализуемые объекты будут работать в AIDL для удаленных служб.

Я просто использую GSON -> Serialise to JSON String -> Восстановить объект из JSON String.

Кроме того, Parcelable предлагает пользовательскую реализацию, когда пользователь получает возможность посылки каждого из своих объектов, переопределяя writeToParcel (). Однако сериализация не является этой настраиваемой реализацией, так как ее способ передачи данных включает API отражения JAVA.