【问题标题】:android - java - pass values through intents, bundles or Parcelables?android - java - 通过意图、捆绑或 Parcelables 传递值?
【发布时间】:2015-04-13 14:33:25
【问题描述】:

上下文:

安卓

我在网上阅读了很多关于在活动之间传递数据的示例。

我学到了什么:

  • 通过 Intent 传递原始数据 (intent.putExtra(key,value))
  • 捆绑原始数据并将其放入intent.putExtra(key,bundle object)
  • Parcelables -> 用于复杂对象和基元。

在你说之前,是的,我肯定错过了什么。

问题:

嗯,似乎有多种方法可以实现同一个目标。

如果我想传递一个自定义对象,Parcelable 是我的人选。但是我仍然需要“序列化”它,所以最后我也会有原语,对吧?

要传递原语,为什么我要在直接传递意图时使用捆绑包?

android 文档/论坛/博客示例不适合我。我的 C 背景仍然让我有点退缩。

顺便说一句,为什么要使用 3 种不同的方式来实现一个目标?

【问题讨论】:

  • Parcelable 更高效。使用parcelabler.com 制作您的包裹。 Bundles 可以包含 parcelables。
  • 那么,是这样吗?对于我所有的情况,我应该忘记其他可能性,只使用 Parcelable ?那为什么另一个还在呢?向后兼容?
  • 或者更好的是,尽量不要在活动之间传递大对象,而是传递id's 并从缓存中检索对象,等等。 ;)
  • @MartínMarconcini:这非常有趣 => 你的意思是我应该用 R.blah 把它拿回来?
  • 好吧,我不知道你想传递什么,但是序列化的整个概念会产生很多开销。对于一些小事情,这可能没问题,但也许你应该问自己,为什么我需要在活动之间传递这个“复杂”对象?如果有一个共同的地方(缓存?)存储这些东西并且我只有一种简单的方法来检索它们,那不是更好更干净吗?然后你只传递一个带有“键”的整数或字符串。我的评论不直接回复你的问题,但应该给你另一个观点

标签: java android android-intent bundle parcelable


【解决方案1】:

但我仍然需要“序列化”它,所以最后我也会有原语,对吧?

Java 中的几乎所有内容最终都归结为原语。

要传递原语,为什么我要在直接传递意图时使用捆绑包?

任何一种方式都有效。使用任何让您感觉更舒适的方法。但是,请注意键上的冲突(例如,您的活动和您继承的一些基本活动,两者都试图将相同的东西放在 IntentBundle 的同一个键中)。

顺便说一句,为什么要使用 3 种不同的方式来实现一个目标?

我猜“一个目标”是“将数据从一个活动传递到另一个活动”。这涉及进程间通信 (IPC),即使这两个活动在同一个进程中,因为核心 OS 进程参与路由。对于标准 Android 中来自 ContentProvider 的流之外的几乎所有内容,IPC 意味着必须将数据放入 Parcel 中,该 Parcel 会被转换为字节数组以通过进程边界。

Parcelable 表示可以添加到自定义类的接口,以允许将它们放入Parcel

Bundle 是一个具体的类,它实现了Parcelable 并代表了一个类似HashMap 的结构,但是强类型化了已知能够进入Parcel 的事物。对于开发人员来说,BundleParcel 更方便,因为它提供了密钥随机访问,而 Parcel 没有。

Intent extras 只是 BundleIntent 公开了它自己的访问器方法。

对于我所有的情况,我应该忘记其他可能性,只使用 Parcelable 吗?

AFAIK,EpicPandaForce 指的是SerializableParcelable 之间的比较。可以进入BundleParcel。在这两者中,在其他条件相同的情况下,Serializable 速度较慢,因为它假定序列化表单必须是持久的,能够在数月或数年后再次读取。 Parcelable 假设每个人都在使用相同的类定义,因此可以绕过一些 Serializable 开销。

话虽如此,这是一个微优化。

那为什么另一个人还在呢?

并非所有东西都可以扩展Parcelable,尤其是java.* 类。例如,Integer 不是 Parcelable。然而,我们希望能够传递intInteger 值。因此,Parcel 支持 intBundle 也是如此。

你的意思是我应该用 R.blah 把它拿回来

AFAIK,在该评论中,Marconcini 先生将“id”作为一般概念,而不是专门指 R.id 值。例如,如果您要维护图像缓存,而不是传递实际的 Bitmap 对象,则传递一些指向缓存的标识符。

【讨论】:

  • 是的,谢谢 Commons,我指的是这个。传递key 并再次检索。在我看来,对于一件小事,传递一个 Serializable/Parceable 对象是“很好”的,但在大多数情况下,最好保持一切干净,并拥有一个可靠的缓存/检索机制。
  • 难道没有办法只发送一个int,这将是一个对象的唯一ID?
  • @Larry:“我怎么能通过两个活动都可以理解和查找/重建的 id 将它传递给另一个活动?” -- 在很多情况下这都能正常工作,通常是因为您已经有一些集中式数据存储(例如,单例缓存管理器)。
  • @Larry:“所以我计划通过的每个项目都应该创建并驻留在单例中”——可能不是。 “每个”是一个非常强大的术语。不同的情况需要不同的方法。
  • @Larry 看看 Realm DB(realm.io 是 URL)。这是一种无需处理 SQLite 即可持久化信息的非常简单的方法。
【解决方案2】:

如果您要传递具有不可序列化的对象,建议使用 Parcelable。这意味着您可以自己实现对象的可序列化表示,以确保数据是您期望在活动之间来回传递的数据。

如果你要传递一个简单的 id 或一个字符串,一定要使用 intent.putExtra()

我发现这篇关于该主题的文章对于帮助理解选项之间的区别和好处非常有用: http://www.developerphil.com/parcelable-vs-serializable/

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-03-11
    • 2012-11-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-11-13
    • 2016-12-05
    相关资源
    最近更新 更多