在应用程序中,在活动之间传递自定义对象的最佳方法是什么?

时间:2011-08-30 06:17:36

标签: android

我知道这个问题被多次询问过,而且我已经经历了很多这些问题......几乎所有这些问题都会让你的课程使用可分割界面。 然而,在几个问题中,我遇到了一个引文:

“注意:看到Parcelable可能触发了这个问题,为什么Android没有使用 内置的Java序列化机制?事实证明,Android团队得出结论 Java中的序列化太慢而无法满足Android的进程间通信 要求。因此,团队构建了Parcelable解决方案。 Parcelable方法需要 您明确地序列化了您的类的成员,但最终,您得到了更快 序列化您的对象。 还要意识到Android提供了两种允许您将数据传递给另一种机制的机制 处理。第一种是使用intent将bundle传递给activity,第二种是传递a 可分配给服务。 这两种机制不可互换,不应该互换 困惑。也就是说,Parcelable并不意味着传递给活动。如果你想要开始 一个活动并传递一些数据,使用一个包。 Parcelable只能作为一部分使用 AIDL定义。“

此引用也可以在Pro Android 2中找到。

现在看到同一个应用程序中的所有活动都在同一个进程中运行(Every Activity in Android is a Process,or One Application is one process),除非清单中另有说明,否则同一应用程序的活动内的通信本身不是进程间通信。所以它是它使用parcelable类真的更快,还是只是通过意图通过bundle传递你的对象属性?

在这方面消除任何亮点都将受到重视。 干杯!!

3 个答案:

答案 0 :(得分:8)

有一个FAQ。 :)

简短的回答是,Android团队推荐了三种在应用程序中的活动和服务之间传递数据的技术:单例类;公共静态字段或方法; WeakReferences to Objects的HashMap(并在intent中传递密钥)。要记住的主要问题是您的数据在各种生命周期事件下的行为方式。 (例如,如果用户打开手机,默认情况下您的活动将被销毁并重新创建;您的数据处理方法需要考虑到这一点。)

答案 1 :(得分:5)

Parcelable构造旨在快速跨应用程序内存边界传递数据:在应用程序中,使用Bundle可以更好地服务,因为发送方可以访问存储数据的所有内存位置和接收器。由于可以访问内存中的对象,因此不需要承担重建的成本:只需使用Bundle,它实际上只是一个带有特定类型的put / get方法的美化HashMap

对于AIDL和IPC目的,您不能(默认情况下)共享内存位置,因此您需要一种有效的数据移动方式:这是Parcelable启动的地方。除非您的应用程序的某个组件正在使用remote流程功能则无需使用Parcelable

答案 2 :(得分:1)

来自docs

  

<强> Parcelables并

     

Parcelable协议提供了极高的效率(但是   用于从中写入和读取对象的对象的低级协议   包裹。你可以使用直接方法writeParcelable(Parcelable,   int)和readParcelable(ClassLoader)或writeParcelableArray(T [],int)   和readParcelableArray(ClassLoader)来写或读。这些方法   将类类型及其数据写入Parcel,允许这样做   稍后从适当的类加载器重构的类   读数。

     

还有一些方法可以提供更有效的工作方式   与Parcelables:writeTypedArray(T [],int),writeTypedList(List),   readTypedArray(T [],Parcelable.Creator)和readTypedList(List,   Parcelable.Creator)。这些方法不会写类信息   原始对象:相反,read函数的调用者必须   知道什么类型的期望和传递适当的   Parcelable.Creator代替正确构造新对象和   阅读其数据。 (为了更高效地写入和读取单个Parceable   对象,可以直接调用Parcelable.writeToParcel和   Parcelable.Creator.createFromParcel自己。)

     

<强>捆绑

     

可以使用名为Bundle的特殊类型安全容器   异构值的键/值映射。这有很多优化   在读取和写入数据时提高性能,以及它   类型安全的API避免了最终难以调试类型错误   将数据内容编组到包中。使用的方法是   writeBundle(Bundle),readBundle()和readBundle(ClassLoader)。