如何在 Android 上将对象从一个活动传递到另一个活动? [复制]

Posted

技术标签:

【中文标题】如何在 Android 上将对象从一个活动传递到另一个活动? [复制]【英文标题】:How do I pass an object from one activity to another on Android? [duplicate] 【发布时间】:2011-02-23 19:35:25 【问题描述】:

我需要能够在我的应用程序的多个活动中使用一个对象,并且它必须是 相同的 对象。做这个的最好方式是什么?

我尝试将对象设置为“公共静态”,以便其他活动可以访问它,但由于某种原因,这并没有削减它。还有其他方法吗?

【问题讨论】:

【参考方案1】:

当您创建意图对象时,您可以利用以下两种方法 用于在两个活动之间传递对象。

putParcelable

putSerializable

您可以让您的类实现Parcelable 或Serializable。然后,您可以跨活动传递您的自定义类。我发现这非常有用。

这是我正在使用的一小段代码

CustomListing currentListing = new CustomListing();
Intent i = new Intent();
Bundle b = new Bundle();
b.putParcelable(Constants.CUSTOM_LISTING, currentListing);
i.putExtras(b);
i.setClass(this, SearchDetailsActivity.class);
startActivity(i);

在新开始的活动中,代码将是这样的......

Bundle b = this.getIntent().getExtras();
if (b != null)
    mCurrentListing = b.getParcelable(Constants.CUSTOM_LISTING);

【讨论】:

我很久以前就解决了这个问题,但我认为你的回答值得接受。 你能告诉我你是如何实现 Parcelable 方法的吗? currentListing 应该是 Parcelable 类型的吧? 当然,它来自我自己的类,它不是标准的android类。我所说的只是使用一些常量作为键! 您是否有理由将Bundle 作为额外的i.putExras(b) 而不是简单地通过Intent.putExtra(String name,Parcelable value) 直接放置Parcelable 对象,然后通过Intent.getParcelableExtra(String name) 检索? 我强烈推荐Parceler library 处理对象的打包【参考方案2】:

您可以创建Application 的子类并将您的共享对象存储在那里。只要有一些活动组件,Application 对象就应该存在于您的应用程序的整个生命周期中。

从您的活动中,您可以通过getApplication() 访问应用程序对象。

【讨论】:

好的,这对我来说是新的。我将如何实现? 我最终实际做的是使该对象成为我的启动活动的受保护成员,然后直接从其他活动中引用该变量。这不完全是 Erich 的回答,但正是他的回答给了我这个想法 @TenFour04 通过清单中的 元素设置它。 @TenFour04 这是很久以前的事了,我的方法发生了很大变化。我找到了很多解决这个问题的方法。从可通过类访问器访问的 Singleton 对象到实现 Serializable 接口的任何内容。基本上,我并没有试图回避这个问题,而是赞同谷歌的方法。但是,如果有问题的对象需要存在于应用程序范围内,@Erich 的答案是一个很好的解决方案。 我也认为这是一个坏主意,因为当应用程序进程被杀死时,Application 对象及其所有局部变量都会被破坏。当用户想要从最近的应用程序堆栈中再次打开应用程序时,它会重新创建最后显示的活动。如果此活动依赖于以前存储在 Application 对象中的值,您将遇到问题,因为这些值不再存在。有关更多信息,请参阅此博客文章:Don't Store Data in the Application Object【参考方案3】:

此答案特定于要传递的对象具有嵌套类结构的情况。使用嵌套类结构,使其 Parcelable 或 Serializeable 有点繁琐。并且,序列化对象的过程是not efficient on Android。考虑下面的例子,

class Myclass    
  int a;
  class SubClass    
       int b;
  

使用谷歌的GSON library,可以直接将一个对象解析为JSON格式的String,使用后转换回对象格式。例如,

MyClass src = new MyClass();
Gson gS = new Gson();
String target = gS.toJson(src); // Converts the object to a JSON String

现在您可以将此字符串作为带有活动意图的 StringExtra 跨活动传递。

Intent i = new Intent(FromActivity.this, ToActivity.class);
i.putExtra("MyObjectAsString", target);

然后在接收活动中,从字符串表示中创建原始对象。

String target = getIntent().getStringExtra("MyObjectAsString");
MyClass src = gS.fromJson(target, MyClass.class); // Converts the JSON String to an Object

它使原始类保持清洁和可重用。最重要的是,如果这些类对象是从 Web 以 JSON 对象的形式创建的,那么此解决方案非常高效且省时。

更新


虽然上述方法适用于大多数情况,但出于明显的性能原因,请不要依赖 Android 的捆绑额外系统来传递对象。有许多解决方案使这个过程灵活高效,这里有一些。每个都有自己的优点和缺点。

    Eventbus Otto

【讨论】:

这是最好的答案 序列化到 GSON 有效吗?速度够快吗? @osrl 对于 pojos,Gson 的运行速度非常快。尽管建议使用事件总线解决方案。请参考答案中的更新。 什么是初步数据类型? @PeterMortensen 没关系。对不起我的英语。【参考方案4】:

也许这是一个不受欢迎的答案,但在过去,我只是简单地使用了一个类,该类具有对我想通过活动持续存在的对象的静态引用。所以,

public class PersonHelper

    public static Person person;

我尝试使用 Parcelable 接口路径,但遇到了许多问题,而且代码中的开销对我没有吸引力。

【讨论】:

这是一个很好的解决方案,但并不总是最佳选择。如果您不喜欢 Parcelable,并且如果您的对象可以简化为基本类型(int、float、double、boolean)和字符串,那么实现 Serializable 接口非常容易。您几乎不需要任何工作,而且开销很小。 @mtmurdock:被序列化的对象是序列化时状态的“快照”吗?我需要将一个对象传递给一个服务,它会在服务的运行时发生变化。服务应始终使用最新的对象,而不是旧的、准复制的对象。 @stk 是的,序列化对象是一个快照。更准确地说,它是一个副本,这意味着在一个活动中更改它不会影响另一个活动,除非您将其传回。服务是一种很好的方式,但我可以理解为什么有人会觉得这有点矫枉过正。另一种解决方案是使用 Android 内置的持久对象存储来保存数据。它可能适合也可能不适合您的需求,但如果您需要能够在整个应用程序中获取/设置值,它不是一个糟糕的解决方案,可用于保存持久数据。【参考方案5】:

这取决于您需要访问的数据类型。如果您有某种需要在Activitys 中持续存在的数据池,那么 Erich 的答案就是要走的路。如果您只需要将一些对象从一个活动传递到另一个活动,那么您可以让它们实现Serializable 并将它们传递到Intent 的附加部分中以启动新的Activity

【讨论】:

这可能是最好的解决方案,只要您的对象不需要在应用程序的生命周期内持续存在(@Erich Douglas 的回答涵盖了这一点)。【参考方案6】:

您的对象也可以实现 Parcelable 接口。然后您可以使用Bundle.putParcelable() 方法并在意图内的活动之间传递您的对象。

Photostream 应用程序使用这种方法,可以用作参考。

【讨论】:

以上是关于如何在 Android 上将对象从一个活动传递到另一个活动? [复制]的主要内容,如果未能解决你的问题,请参考以下文章

如何在android studio中将堆栈从一个活动传递到另一个活动

在android中将值从一个窗口传递到另一个窗口

如何将 Bitmap 对象从一个活动传递到另一个活动

如何将不可打包的对象从活动传递到另一个活动?

从 android Activity 传递到 Fragment 的 Parcelable 对象

如何在GET上将变量从一个页面(视图)传递到另一个页面?