序列化与 Parcelable Android
Posted
技术标签:
【中文标题】序列化与 Parcelable Android【英文标题】:Serialization v/s Parcelable Android 【发布时间】:2011-12-05 14:45:23 【问题描述】:从事缓存项目。想用android上的文件系统来做。 我知道数据库也是一种选择,但想尝试文件系统。
在 Android 中使对象可序列化,使用 ObjectOutputStream 和 ObjectInputStream 来序列化和反序列化整个对象数组列表非常容易。
它还允许在两个活动之间传递对象。但是,当读取 250 个节点列表时,我的应用程序的加载时间增加了 5 倍。
我知道 parcelable 也是传递部分,是 Android 的序列化方式。但是,任何人都知道如何将 parcelable 与 ObjectOutputStream 一起使用,以便充分利用 Android 的序列化。
另外,如果有人知道如何加快 readObject 和 writeObject 的序列化速度,请分享。通过这样做可以实现多大的不同,这样做是否可取。
或者是在 android 的情况下,数据库方式是缓存的唯一选择。不要忘记预缓存也可以通过 db 来实现,但我们可以吗?
【问题讨论】:
【参考方案1】:不要使用包裹。根据 Android 文档 (http://developer.android.com/reference/android/os/Parcel.html):
Parcel 不是通用的序列化机制。此类(以及用于将任意对象放入 Parcel 的相应 Parcelable API)被设计为高性能IPC transport。因此,将任何 Parcel 数据放入持久存储是不合适的:Parcel 中任何数据的底层实现发生变化都可能导致旧数据不可读。
让一个对象实现可序列化的接口也是有风险的,因为那样你就会被绑定到那个序列化格式。如果您将来更改对象,您将在读取在旧机制下序列化的对象时遇到问题。
使用数据库可能是将内容缓存到磁盘的最佳选择。
【讨论】:
如果您不喜欢 sqlite,请查看 db4o.com 它的开源和 - 对于 android 完全免费 -。您可以像 save(Object o) 一样保存对象并像 get(MyOwnObject.class) 一样检索以获取所有存储的对象 你的意思是如果你将你的对象传递给服务器,序列化是有风险的? Activity 到 Activity 的序列化更加安全。 能否提供此声明的链接? @Blundell 不,我的意思是实现序列化接口是有风险的,期间。有关实现可序列化接口的风险的详细信息,请查看macchiato.com/columns/Durable4.html @Kurtis Ah 当然,如果用户使用 v1.3 序列化一些数据并且您将对象更改为 1.4 版本,您可能会丢失他们保存的内容。感谢您的链接,我今晚的睡前阅读;-)【参考方案2】:我不知道它是否有效,所以它只是一个想法: 尝试使用 Parcel 对象本身:
使用Parcel.obtain
检索一个新实例
用writeToParcel(Parcel source)
写你所有的Parcelable Objects
然后,如果您想将值写入文件系统,请调用 marshall()
以获取字节。
用 ByteInputStream 或类似的东西写下来
再读一遍,调用 unmarshall,然后调用 ParcelableCreators
【讨论】:
【参考方案3】:序列化很慢,因为它使用反射,非常慢。只有完全避免序列化,才能避免这种情况。
ObjectOutputStream 可以通过 ByteArrayOutputStream 产生字节数组。然后您可以使用parcel.writeByteArray(byte[])
将字节数组保存到包裹中。这仍然会很慢。
【讨论】:
但是要使用 ObjectOutputStream 我们不需要实现可序列化而不是可打包的对象吗? 您可以在您的包装对象上使用 Parcelable,在您实际想要存储的所有对象中使用 Serializable。 我根本不需要 Parcelable,我可以使用 Serializable。但正如我提到的,对于 250 个节点的树,它需要 5 秒而不是之前的 1 秒。显着降低性能。 5 秒是从文件系统加载它而不是在活动之间传递。以上是关于序列化与 Parcelable Android的主要内容,如果未能解决你的问题,请参考以下文章