Java 在Android中将对象引用保存到Bundle

Java 在Android中将对象引用保存到Bundle,java,android,Java,Android,是否可以将对对象的引用保存在捆绑包中? 不是整个对象,只是引用 例如,Bundle类有方法get对象,但我找不到put或set方法 我需要它,因为在活动中,我创建了timer类的一个实例,然后启动计时器:myTimer.start() 如果我必须重新启动活动,我想将计时器恢复到以前的值。您不能。您只能传递有限的一组数据类型,正如您所看到的,并且如果您需要多个原语,那么您的类需要实现接口(或使用类似于helper的方法)。完成后,您将能够通过Bundle传递对象数据(但仍然不是对象本身)希望您不能

是否可以将对对象的引用保存在捆绑包中?
不是整个对象,只是引用

例如,
Bundle
类有方法
get
对象,但我找不到
put
set
方法

我需要它,因为在活动中,我创建了timer类的一个实例,然后启动计时器:
myTimer.start()


如果我必须重新启动活动,我想将计时器恢复到以前的值。

您不能。您只能传递有限的一组数据类型,正如您所看到的,并且如果您需要多个原语,那么您的类需要实现接口(或使用类似于helper的方法)。完成后,您将能够通过Bundle传递对象数据(但仍然不是对象本身)

希望您不能这样做。您只能在bundle中存储原语。正如Marcin Orlowski提到的,“存储”整个对象可以通过实现接口来实现。“存储”是指存储对象状态。实现此接口有助于在不同的代码段中持久化对象状态,而无需将其所有属性反复放入
Bundle
对象


当活动进入暂停状态时,您的活动使用的所有对象迟早都会被垃圾收集器删除,所以存储对它们的引用是愚蠢的

官方文档建议在“配置更改”期间使用片段来存储引用(不,我不认为这意味着您需要将活动作为片段进行休息,而是使用片段作为存储介质(需要澄清)):

在配置更改期间保留对象

JsonElement json = new JsonElement();
String result = gson.toJson(json);
bunlde.putString("key",result);
如果重新启动活动需要恢复大量数据集,请重新建立 网络连接,或执行其他密集操作,然后 由于配置更改而重新启动可能是一种缓慢的用户体验。 另外,您可能无法完全恢复 系统使用为您保存的捆绑包的活动状态 onSaveInstanceState()回调函数的设计目的不是承载大型 对象(如位图)及其内的数据必须序列化 然后反序列化,这会消耗大量内存并使 配置更改缓慢。在这种情况下,您可以减轻 通过保留一个片段来重新初始化活动的负担 由于配置更改,您的活动已重新启动。这 片段可以包含对您想要创建的有状态对象的引用 保留

当Android系统因故障而关闭您的活动时 配置更改,您拥有的活动片段 标记为保留的文件不会被销毁。您可以将这些片段添加到 保留有状态对象的活动

在运行时将有状态对象保留在片段中 配置更改:

扩展Fragment类并声明对有状态对象的引用 物体。创建片段时调用setRetainInstance(布尔值)。 将片段添加到您的活动中。使用FragmentManager检索 活动重新启动时的片段。例如,定义您的 片段如下:

注意:虽然您可以存储任何对象,但千万不要通过 绑定到活动的对象,例如可绘制、适配器、 视图或与上下文关联的任何其他对象。如果你这样做, 它将泄漏原始活动的所有视图和资源 例如。(泄漏资源意味着您的应用程序维护 抓紧它们,它们就不能被垃圾收集,所以内存很大 可能会丢失。)


另一种方法是将POJO转换为json,然后将GSON库字符串化,并将其另存为字符串。然后将其作为字符串从bundle中检索回来,并使用相同的GSON库将其转换回object。下面是示例代码

将JSON转换为字符串并保存在bundle中

JsonElement json = new JsonElement();
String result = gson.toJson(json);
bunlde.putString("key",result);
再次将字符串从捆绑包转换为对象

 JsonElement json = gson.fromJson(bundle.getString("key"), JsonElement.class);

所以,每次他们旋转设备时,我都会重新创建每个对象?事实上,是的。因为您的活动是在设备旋转期间重新创建的。在每个
活动
和其他类似类上都调用了
onSaveInstanceState
方法,这样您就可以将对象的状态保存在那里,然后在
onCreate
方法中重新创建它们。如果已将活动状态保存在
onSaveInstance
方法中,则
onCreate
方法的
Bundle
参数不应为空。但是,有一种方法可以避免方向更改期间的活动重新创建-覆盖配置更改的方法,并且不允许调用它的超级方法。检查这个:我的答案太长了,所以我无法将链接附加到适当的线程,这里是:非常感谢,太棒了!我知道最好的办法是让屏幕刷新并处理它,但在这一刻我可以避免这个问题并继续学习。@Garet,为什么这么做很愚蠢?这些对象也可以从其他地方引用(例如,应用程序类),因此在活动暂停时不必进行GC。这并不能真正回答问题,这是关于存储对对象的引用,而不是对象本身。Parcelable用于存储对象,与Serializable非常相似,但是您需要自己实现“编组”。它与Java如何管理对象无关。您已经解释了如何存储对象,而不是它的引用,这正是问题所在。如果您中的任何人花了一点时间查看文档,那么应该清楚为什么。请尝试-Bundle-put iBinder-in iBinder您的对象