Parcelable android для чего

Parcelable. Передаём объекты

Очень часто программисту приходится передавать данные из одной активности в другую. Когда речь идёт о простых типах, то используется метод intent.putExtra() и ему подобные. Данный способ годится для типов String, int, long или массивов. А вот объекты таким образом передать не получится.

В Java существует специальный интерфейс Serializable, но он оказался слишком неповоротлив для мобильных устройств и пользоваться им настоятельно не рекомендуется. Для передачи объектов следует использовать другой интерфейс Parcelable.

В интерфейсе Parcelable используются два метода describeContents() и writeToParcel():

Метод describeContents() описывает различного рода специальные объекты, описывающие интерфейс.

Метод writeToParcel() упаковывает объект для передачи.

Также необходимо реализовать статическое поле Parcelable.Creator CREATOR, которое генерирует объект класса-передатчика.

Напишем пример. Попробуем передать объект «Мои документы». Как известно, признаком настоящего документа являются Усы, лапы, хвост (я ещё добавил бы имя). Создадим новый класс DocumentInfo, который реализует интерфейс Parcelable:

Теперь мы может передать объект через Intent. Создадим две активности. В первой активности напишем код для отправки объекта:

Вторая активность должна принять данные от первой активности:

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

Если класс слишком большой, то вручную его переделывать утомительно. Существует онлайн-сервис parcelabler а также плагин для Android Studio mcharmas/android-parcelable-intellij-plugin: IntelliJ Plugin for Android Parcelable boilerplate code generation.

Источник

Parcelable vs Serializable

Apr 23, 2017 · 4 min read

Often, when we develop applications, we have to transfer data from one Activity to another. Of course, we can not do that directly. The data we want to transfer must be included into a corresponding Intent object. And if we want to move a complex POJO (e.x. Person, Car, Employee, etc.) we also need to perform some additional actions to make that object suitable for a transfer. To do that, our object must be either Serializable or Parcelable.

What is Serializable?

Serializable is a stan d ard Java interface. It is not a part of the Android SDK. It’s simplicity is it’s beauty. Just by implementing this interface your POJO will be ready to jump from one Activity to another. In the following code snippet you can see how simple it is to use this interface.

Because Serializable is a marker interface, we don’t have to implement tons of extra methods. When we ‘mark’ our POJO with it, Java will try it’s best to serialize it.

Of course, this simple approach has it’s price. Reflection is used during the process and lots of additional objects are created along the way. This can cause lot’s of garbage collection. The result is poor performance and battery drain.

What is Parcelable?

Parcelable is another interface. Despite it’s rival (Serializable in case you forgot), it is a part of the Android SDK. Now, Parcelable was specifically designed in such a way that there is no reflection when using it. That is because, we are being really explicit for the serialization process. In the code snippet down below you can see a sample usage of the Parcelable interface:

Of course, there is a price we have to pay when using Parcelable as well! Because of the boilerplate code, it is much harder to maintain and understand the POJO from above.

Parcelable VS Serializable

If you search through the web for info on this topic, you will most probably come to the conclusion that there won’t be an absolute winner for this comparison. There are people and articles out there, which support either the one, or the other approach. Thus, I will present you both sides and leave you to decide for yourself!

The first ‘team’ stands behind the idea that Parcelable is way faster and better than Serializable. Of course, there is data behind this statement.

Читайте также:  Smart wallpaper для android

The results from the tests conducted by Philippe Breault show that Parcelable is more than 10x faster than Serializable. Some other Google engineers stand behind this statement as well.

You can find a link to Philippe’s article in the ‘References’ section down below.

Now, the second ‘team’ claims that we are all doing it wrong! And their arguments sound reasonable enough!

According to them, the default Serializable approach is slower than Parcelable. And here we have an agreement between the two parties! BUT, it is unfair to compare these two at all! Because with Parcelable we are actually writing custom code. Code specifically created for that one POJO. Thus, no garbage is created and the results are better. But with the default Serializable approach, we rely on the automatic serialization process of Java. The process is apparently not custom at all and creates lots of garbage! Thus, the worse results.

Now, there is another approach. The whole automatic process behind Serializable can be replaced by custom code which uses writeObject() & readObject() methods. These methods are specific. If we want to rely on the Serializable approach in combination with custom serialization behavior, then we must include these two methods with the same exact signature as the one below:

Strange! Weird! Unusual! But that’s how it works! Now, in these two methods we can include our custom logic. If done correctly, the garbage associated with the default Serializable approach will not be a factor anymore!

And now a comparison between Parcelable and custom Serializable seems fair! The results may be surprising! The custom Serializable approach is more than 3x faster for writes and 1.6x faster for reads than Parcelable. You can find a BitBucket project with test data in the ‘Resources’ section to play with.

In my opinion, the differences in speed between the two approaches will be almost insignificant in most of the cases. Thus, at the end of the day, it is rather more important to get the job done and to have happy users, than to have an app running with 0.000042 milliseconds faster.

Источник

Русские Блоги

Android два метода сериализации Serializable и Parcelable

Что такое сериализация

Мы всегда говорим или слышим о «сериализации». Каково ее определение?

Сериализация (сериализация) Процесс преобразования информации о состоянии объекта в форму, которая может быть сохранена или передана. Во время сериализации объект записывает свое текущее состояние во временное или постоянное хранилище. Позже вы можете воссоздать объект, прочитав или десериализуя состояние объекта из области хранения.

Двоичная сериализация поддерживает точность типов, что полезно для сохранения состояния объектов между различными вызовами приложения. Например, сериализуя объект в буфер обмена, вы можете использовать его в разных приложениях. Вы можете сериализовать объекты в потоки, диски, память, сети и т. Д. Удаленное взаимодействие использует сериализацию для передачи объектов между компьютерами или доменами приложений «по значению».

Проще говоря, «сериализация» — это преобразование состояния объекта во время выполнения в двоичное, а затем сохранение его в потоке, в памяти или передача на другие терминалы по сети.

В разработке под Android мы часто используем Intent при передаче данных в компонентах. При передаче данных нам необходимо передать Serializable или Parcelable данные, такие как метод Intent.putExtra:

Binder также будет использоваться для передачи данных.

Сегодня я представлю эти два метода сериализации.

Сериализуемый интерфейс

Serializable — это интерфейс сериализации, предоставляемый Java, это пустой интерфейс:

Serializable используется для идентификации текущего класса, может быть ObjectOutputStream Сериализация и бытие ObjectInputStream Десериализация.

Serializable имеет следующие характеристики:

  • В сериализуемом классе состояние атрибута, которое не реализует Serializable, не может быть сериализовано / десериализовано
  • Другими словами, в процессе десериализации класса его несериализуемые свойства будут воссозданы путем вызова конструктора без параметров.
  • Следовательно, конструктор без параметров этого свойства должен быть доступен, иначе во время выполнения будет сообщено об ошибке.
  • Класс, реализующий сериализацию, и его подклассы также сериализуемы.

Ниже приведен класс сущности, реализующий Serializable:

Видно, что реализация Serializable очень проста, за исключением содержимого сущности, просто создайте его serialVersionUID Атрибуты в порядке.

serialVersionUID

По названию видно, что это serialVersionUID Что-то похожее на наш обычный номер версии интерфейса, который однозначно определяет сериализуемый класс во время выполнения.

Читайте также:  Все настройки для андроид планшет

Другими словами, когда класс сериализуется, его номер версии будет сохранен во время выполнения, а затем во время десериализации проверьте, совпадает ли номер версии объекта, который вы хотите десериализовать. Если он не согласован, будет сообщено об ошибке: · InvalidClassException 。

Если мы не создадим этот номер версии сами, среда выполнения вычислит номер версии по умолчанию на основе многих характеристик класса в процессе сериализации. Однако, если вы немного измените этот класс, номер версии изменится. Если это произойдет после сериализации, это вызовет вышеупомянутую ошибку во время десериализации.

Поэтому спецификация JVM настоятельно рекомендует объявлять номер версии вручную. Это число может быть случайным, если оно фиксировано. В то же время лучше оставаться конфиденциальным и окончательным и постараться сохранить его неизменным.

Кроме того, статические и временные измененные атрибуты не сохраняются в процессе сериализации. Первый хорошо понятен, потому что статические атрибуты управляются классом и не принадлежат состоянию объекта; в то время как последний является ключевым словом Java, специально используемым для идентификации непоследовательности. Атрибуты.

Реализация Serializable по умолчанию не будет создана автоматически. serialVersionUID Атрибут, чтобы напоминать нам создавать вовремя serialVersionUID , Можно поискать в настройках serializable Затем выберите несколько вариантов, как показано на рисунке ниже, для тех, кто не заявил serialVersionUID Добавьте предупреждение для классов атрибутов и внутренних классов.

Поэтому, когда мы создаем класс без объявления атрибута UID, на имени класса будет желтое предупреждение:

Содержимое предупреждения будет отображаться при наведении на него мыши:

GroupBean’ does not define a ‘serialVersionUID’ field less… (Ctrl+F1)
Reports any Serializable classes which do not provide a serialVersionUID field. Without a serialVersionUID field, any change to a class will make previously serialized versions unreadable.

В это время мы можем сгенерировать serialVersionUID, нажав комбинацию клавиш для запроса кода.

Сериализация и десериализация Serializable

Сериализация и десериализация Serializable выполняются через ObjectOutputStream и ObjectInputStream соответственно. Пример кода выглядит следующим образом:

Parcelable интерфейс

Parcelable — это интерфейс сериализации, уникальный для Android:

Классы, реализующие интерфейс Parcelable, будут преобразованы в при сериализации и десериализации. Parcel Тип данных.

Parcel является носителем, он может содержать ссылки на данные или объекты, а затем передаваться между процессами через IBinder.

Класс, реализующий интерфейс Parcelable, должен иметь статическую переменную типа CREATOR. Ниже приведен пример:

подводить итоги

Как видите, использование Serializable относительно просто, просто создайте номер версии; хотя Parcelable относительно сложен, необходимо реализовать четыре метода.

Как правило, рекомендуется использовать Serializable при сохранении данных на SD-карту или передаче по сети.Хотя эффективность ниже, им легко пользоваться.

Рекомендуется использовать Parcelable для передачи данных во время выполнения, например Intent, Bundle и т. Д. Нижний уровень Android оптимизирован для обеспечения высокой эффективности.

Thanks

Перевод с: https://blog.csdn.net/u011240877/article/details/72455715

1. Что такое сериализация и десериализация?

(1) Объяснение терминов

Сериализация объекта: процесс преобразования объекта Java в байтовую последовательность и сохранения его на носителе.
Десериализация объектов: процесс восстановления последовательностей байтов в объекты Java.

(2) Подробное объяснение сериализации

Сериализация объектов включает три ключевых момента: объекты Java, последовательности байтов и хранилище.

1. Каков состав объектов Java?
Объекты Java содержат переменные и методы. Но сериализация и десериализация имеют дело только с переменными Java, а не с методами, а сериализация и десериализация имеют дело только с данными.

2. Что такое последовательность символов?
Последовательность символов состоит из двух слов, символ находится в поле компьютера и связи, а символ является единицей информации. Математически последовательность — это объект (или событие), расположенный в ряд.
«Персонажи-Википедия» ,«Последовательность-Википедия»Грубо говоря, это набор из нескольких последовательно расположенных персонажей. Похожие на «1A165613246546»

3. Магазин
Последовательность символов необходимо сохранить в одном месте, которым может быть жесткий диск или память.
Проще говоря: сериализация сохраняет информацию о текущем объекте. Десериализация — прямо противоположная операция.

Во-вторых, чем отличается Java-объект от сериализации Java-объекта?

Предпосылка для существования объектов Java должна существовать во время работы JVM.Если вы хотите получить указанный объект Java, когда JVM не запущена или на JVM другой машины, это невозможно выполнить в рамках существующего механизма объектов Java.
В отличие от объектов Java, если вы выполняете операции сериализации над объектами Java, поскольку принцип заключается в сохранении информации об объекте Java на носителе, вы можете использовать два типа объектов Java, которые не могут существовать. В этом случае объекты Java все еще можно использовать.

3. Зачем использовать сериализацию и десериализацию?

Основываясь на вышеупомянутом понимании сериализации и десериализации, этот вопрос можно перевести на вопрос: почему мне нужно сохранять информацию об объекте на носителе данных и читать ее позже?
Из-за объяснения во втором случае необходимо получить указанный объект Java, когда JVM не запущена или на JVM других машин.

Читайте также:  Как прошить планшет андроид без компьютера ирбис

1. Используйте RMI (удаленный вызов метода)

2. Передача объектов в сети (Java Beans)

3. Глубокая копия объекта (включая сеть отношений между объектами, содержащуюся в текущем объекте)

4. В чем разница между Serializable и Parcelable в Android?

Оба используются для поддержки операций сериализации и десериализации. Самая большая разница между ними — это разница в носителях. Serializable использует ввод-вывод для чтения, записи и хранения на жестком диске, тогда как Parcelable читает и записывает непосредственно в память. Очевидно, что память Скорость чтения и записи обычно выше, чем у ввода-вывода, поэтому в Android обычно предпочтительнее использовать Parcelable.
Сериализуемость не в центре внимания, но вы можете проверить«Анализ алгоритмов сериализации Java»В этой статье реализован простой пример Serializable: просмотрите файл ввода-вывода, сгенерированный сериализацией, прочтите его в шестнадцатеричном формате и по очереди объясните значение каждого шестнадцатеричного числа.

Пять, пример Parcelable

Класс, реализующий интерфейс Parcelable в Android, может поддерживать последовательность и десериализацию. Ниже приведен пример реализации:
1. Реализуйте интерфейс Parcelable.
2. Добавьте атрибуты сущности
3. Переопределите метод writeToParcel (Parcel dest, int flags), чтобы указать данные, которые будут записаны в класс Parcel.
4. Создайте статический объект Parcelable.Creator, есть два метода createFromParcel (Parcel in) и newArray (int size), первый указывает, как читать объекты данных из Parcel, второй создает Массив.
5. Переопределите метод describeContents и верните 0 по умолчанию.

public class Gril implements Parcelable <

private int mAge; // возраст

private boolean mSexy; // Это сексуально

public void writeToParcel(Parcel dest, int flags) <

dest.writeByte((byte) (mSexy ? 1 : 0));

public static final Parcelable.Creator CREATOR = new Parcelable.Creator () <

public Gril createFromParcel(Parcel in) <

Gril gril = new Gril();

gril.mSexy = in.readByte() != 0;

public Gril[] newArray(int size) <

return new Gril[size];

public int describeContents() <

Шесть, принцип посылки

Как видно из приведенного выше примера, конкретная запись (dest.writeInt (mAge);) и чтение (gril.mAge = in.readInt ();) — это все операции, выполняемые над объектом Parcel, опубликованным ниже. Это определение Parcle для чтения и записи данных типа int.

public final class Parcel <

* Write an integer value into the parcel at the current dataPosition(),

* growing dataCapacity() if needed.

public final native void writeInt(int val);

* Read an integer value from the parcel at the current dataPosition().

public final native int readInt();

Из приведенного выше кода видно, что все описания собственных методов используют JNI, а конкретное местоположение — system / frameworks / base / core / jni / android_util_Binder.cpp. Далее также в качестве примера используется чтение и запись типа int.

static void android_os_Parcel_writeInt(JNIEnv* env, jobject clazz, jint val)

Parcel* parcel = parcelForJavaObject(env, clazz);

if (parcel != NULL) <

const status_t err = parcel->writeInt32(val);

if (err != NO_ERROR) <

jniThrowException(env, «java/lang/OutOfMemoryError», NULL);

static jint android_os_Parcel_readInt(JNIEnv* env, jobject clazz)

Parcel* parcel = parcelForJavaObject(env, clazz);

if (parcel != NULL) <

Из вышеизложенного видно, что вызывается реализация Parcel и вызываются функции writeInt32 и readInt32 соответственно, а затем давайте посмотрим на конкретную реализацию. Расположение: /system/frameworks/base/libs/binder/Parcel.cpp

status_t Parcel::writeInt32(int32_t val)

status_t Parcel::writeAligned(T val) <

*reinterpret_cast (mData+mDataPos) = val;

status_t err = growData(sizeof(val));

if (err == NO_ERROR) goto restart_write;

status_t Parcel::readInt32(int32_t *pArg) const

status_t Parcel::readAligned(T *pArg) const <

const void* data = mData+mDataPos;

*pArg = *reinterpret_cast (data);

Следующие 4 балла взяты из«Изучение механизма отправки посылок в Android (часть 1)»
Заинтересованные друзья могут прочитать его сами. Это несложно понять. Вот краткое изложение основных идей:
1. Все чтение и запись выполняются в памяти, в основном с помощью malloc (), realloc (), memcpy () и других операций с памятью, поэтому это более эффективно, чем использование external в сериализации JAVA. Память будет намного выше;
2. При чтении и записи он выравнивается по 4 байтам, вы можете видеть, что #define PAD_SIZE (s) (((s) +3) &

3) выполняет определение макроса это дело;
3. Если предварительно выделенного места недостаточно, newSize = ((mDataSize + len) * 3) / 2; сразу выделит на 50% больше;

4. Для обычных данных используется адрес памяти mData, а для данных типа IBinder и FileDescriptor используется адрес памяти mObjects. Последнее достигается с помощью flatten_binder () и unflatten_binder (), цель состоит в том, что объект, прочитанный во время десериализации, является исходным объектом без необходимости обновлять новый объект.

Семь, сериализация и десериализация Parcelable эксперимент?

Источник

Оцените статью