Сериализация в / с Parcelable Android

#java #android #serialization

#java #Android #сериализация

Вопрос:

Работаю над проектом для кэширования. Хотелось бы сделать это с файловой системой на Android. Я знаю, что база данных также является опцией, но хочу попробовать файловые системы.

Создание сериализуемого объекта в случае Android очень просто использовать ObjectOutputStream и ObjectInputStream для сериализации и десериализации исходного массива объектов, что происходит автоматически.

Это также позволяет передавать объекты между двумя действиями. Однако время загрузки моего приложения увеличилось в 5 раз при чтении списка из 250 узлов.

Я знаю, что parcelable также выполняет передающую часть и является способом сериализации Android. Однако у кого-нибудь есть идеи, как использовать parcelable вместе с ObjectOutputStream, чтобы можно было полностью использовать сериализацию Android.

Также, если у кого-то есть идеи, как ускорить сериализацию отдельно для readObject и writeObject, пожалуйста, поделитесь. И, делая это, насколько большой разницы можно достичь и целесообразно ли это делать.

Или способ базы данных является единственным вариантом для кэширования в случае Android. Не забывайте, что предварительное кэширование также может быть достигнуто через db, но мы можем?

Ответ №1:

Не используйте посылки. Согласно документации по Android ( http://developer.android.com/reference/android/os/Parcel.html ) :

Parcel не является механизмом сериализации общего назначения. Этот класс (и соответствующий Parcelable API для размещения произвольных объектов в посылке) разработан как высокопроизводительный транспорт IPC. Таким образом, нецелесообразно помещать какие-либо данные посылки в постоянное хранилище: изменения в базовой реализации любых данных в посылке могут сделать старые данные нечитаемыми.

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

Использование базы данных, вероятно, является вашим лучшим вариантом для кэширования данных на диск.

Комментарии:

1. если вам не нравится sqlite, взгляните на db4o.com его открытый исходный код и — для Android совершенно бесплатно -. Вы можете просто сохранять объекты, такие как save (Object o), и извлекать их, как get (MyOwnObject.class ), чтобы получить все сохраненные объекты

2. Вы имеете в виду, что сериализация является рискованной, если вы передаете свои объекты на сервер? Сериализация от действия к действию намного безопаснее.

3. Не могли бы вы предоставить ссылку на это заявление, пожалуйста?

4. @Blundell нет, я имею в виду, что реализация интерфейса сериализации является рискованной, точка. Для получения подробной информации об опасностях реализации сериализуемого интерфейса выйдите из macchiato.com/columns/Durable4.html

5. @Kurtis Ах, конечно, если пользователь сериализует некоторые данные с версией v1.3, а вы меняете свой объект в версии 1.4, вы можете потерять то, что они сохранили. Спасибо за ссылку, сегодня вечером я читаю перед сном 😉

Ответ №2:

Я не знаю, работает ли это, так что это просто идея: попробуйте использовать сам объект Parcel:

извлеките новый экземпляр с помощью Parcel.obtain

запишите все ваши Parcelable объекты с writeToParcel(Parcel source)

затем, если вы хотите записать значения в вызов файловой системы marshall() , чтобы получить байты.

запишите это с помощью ByteInputStream или чего-то подобного

прочитайте это еще раз, вызовите unmarshall и вызовите ParcelableCreators

Ответ №3:

  1. Сериализация выполняется медленно, потому что она использует отражение, которое выполняется очень медленно. Вы можете избежать этого, только если вы вообще избегаете сериализации.

  2. ObjectOutputStream может создавать массив байтов через ByteArrayOutputStream. Затем вы можете использовать parcel.writeByteArray(byte[]) для сохранения массива байтов в parcel. Это все равно будет медленным.

Комментарии:

1. Но для использования ObjectOutputStream разве нам не нужен объект, который реализует serializable вместо parcelable?

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

3. Мне вообще не понадобится parcelable, я могу просто использовать Serializable. Но, как я уже упоминал, для дерева из 250 узлов это заняло бы 5 секунд вместо 1 секунды ранее. Значительно снижает производительность. 5 секунд — это время загрузки из файловой системы, а не переход между действиями.