意图附加项不是按引用传递的吗?

3

我有一个实现了Serializable接口的自定义类型对象,我能够成功地通过我的活动传递这个对象。

现在情况是这样的:

在第一个活动中,CustomObject实例具有一个String属性,值为“A”,并作为Extra参数传递给第二个活动:

Intent intent = new Intent(getApplicationContext(), Activity_2.class);
intent.putExtra("CUSTOM_OBJECT", customObjectInstance);

startActivityForResult(intent, 0);

在第二个活动中,我从意图中检索CustomObject并将属性值从“A”修改为“B”。当我按返回按钮从Activity 2返回Activity 1时,CustomObject的属性值又变成了“A”!我检查了对象的哈希码,并确认它是两个Activity上相同的实例,但仍然无法弄清楚为什么会发生这种情况。
编辑:
如所请求,关于我设置属性值的代码,它非常简单:在Activity 2上:
CustomObject obj = (CustomObject) getIntent().getExtras().getSerializable("CUSTOM_OBJECT");
obj.setProperty("B");

1
请发布设置属性的代码。Java通过值传递所有内容。当您传递一个“对象”时,您传递了对该对象引用的值的副本。它只是一个长整数。对象存在于内存地址A。Activity 1中对象的实例实际上是存储在地址B中的地址A的指针。Activity 2接收存储在地址C中的此指针的副本。由于指针似乎相同,这些都没有回答您的问题,这很奇怪。请注意,哈希等于并不“保证”相同的对象。http://www.ibm.com/developerworks/java/library/j-jtp05273/index.html - Simon
哈哈,感谢@Simon的帮助。这里的目标是我有一个报告,在Activity 1上有一个“版本”。 Activity 2用于从WebService检索该报告的信息,基于其版本!在进行此操作之前,我会检查版本是否需要更新,如果需要,我会更改版本属性值。此Activity 2在我的应用程序内启动了一个全新的流程,最终回到Activity 1,我希望我的报告实例所做的更改会被反映出来。 - Aquanauta
1
我开始觉得,由于我的对象引用不会通过Intent在所有Activity中“全局”更新,所以每次调用“onActivityResult”方法时,我都会在每个Activity中覆盖我的对象。这样,当第2个Activity返回到第1个Activity时,我将使用第2个Activity的值覆盖第1个Activity的实例。你觉得呢? - Aquanauta
@Simon非常感谢你!我似乎无法在所有帮助我的评论上给你一个“+”,因为它们都是评论。我作为Stack Overflow的新活跃用户,这样做可以吗?我不应该用积极的投票/回复等来奖励你吗? - Aquanauta
1
没关系。很高兴能帮忙,只希望你最终得到一个更清洁、更易于维护的解决方案。我之所以给予,是因为我也从中获益良多。我学到了大部分深入的知识都来自这里,所以回馈足以滋养灵魂。 - Simon
显示剩余5条评论
2个回答

2

Intent的extras只包含值。你可以通过扩展Application类和部署“全局”变量来处理参数引用。

尽管你表达了两个对象的哈希码相同,但我非常确定每个Activity都处理其自己的一组局部变量。在你的测试中,活动A和B中的对象是彼此独立的。

希望这有所帮助。


不好意思,但完全是胡说八道。Java通过值传递所有东西。对象实例作为引用指针值的副本进行传递。此外,建议使用全局变量来解决这个问题完全违背面向对象编程的原则。"我非常确定每个Activity都处理自己的一组变量"。我猜你是指类字段,如果不是静态的,还有其他方法可以处理吗? - Simon
1
@Aquanauta 听起来有点过头了。多个活动真正需要访问同一对象的情况很少。听起来你正在创建一些具有状态的“上帝”对象。你想做什么?可能有更清晰的设计方案。 - Simon
您可以将类似"上帝"的值保存/更新到SharedPreferences中,并在每次需要使用时检索它们。 - Andres
1
这通常取决于你所说的“状态”类型。SharedPreferences写入文件,因此通常应保留为当您需要跨应用程序启动/停止保持持久状态时使用。如果您不需要持久状态,并且您需要存储的内容可以适合内存,请勿使用文件系统(或SQL等)。相反,使用Application对象(具有良好定义的生命周期并且是获取/设置东西的完美位置,尽管我不会称其为“全局”),甚至使用静态变量(但要小心静态变量,通常由Application管理是最佳选择)。 - Charlie Collins
1
@CharlieCollins,还是很危险的Charlie。很容易做出像new CustomObject(this)这样的事情(因为你想要访问资源),除非你在活动销毁时记得将该上下文设置为空,否则会导致大量内存泄漏。 - Simon
显示剩余3条评论

0

你在Activity中调用了setResult(int)返回结果吗?这里是有关启动带返回结果的Activity的文档。

它必须始终提供一个结果代码,可以是标准结果RESULT_CANCELED、RESULT_OK或任何以RESULT_FIRST_USER开头的自定义值。此外,它还可以选择性地返回包含任何其他数据的Intent。所有这些信息都会出现在父Activity.onActivityResult()上,以及它最初提供的整数标识符。

如果子Activity由于任何原因(例如崩溃)失败,则父Activity将收到一个带有代码RESULT_CANCELED的结果。

http://developer.android.com/reference/android/app/Activity.html#StartingActivities


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接