在Android中的活动之间共享复杂的对象树的好方法?

这是我现在为我构建的一些不同应用程序提出的一个问题,我还没有对我提出的任何解决方案感到满意。 我想我会把它放到社区那里看看可能有的其他解决方案。

假设你有一个Activity来下载一个复杂的数据树(在这种情况下通过json,但它可以是任何东西),将数据解组为一组java对象(在这种情况下使用gson,但同样可以是其他) ,然后产生其他活动以查看该数据的不同部分。 可能有一项活动可以在您的回复中查看旅行,另一项活动可以查看这些旅行中的航class,也可以查看另一项活动来查看这些航class的乘客。

我最初实现这个应用程序是在第一个活动中解组所有Trips,然后通过值(作为意图中的额外)传递给TripActivity。 然后,TripActivity将单个航class传递给FlightActivity,依此类推。

这样做的问题是,当应用程序序列化和反序列化数据时,活动之间会有明显的暂停。 我们说几秒钟。 当我的树使用Serialization或Parcelable传递数据时,暂停非常明显。 使用google的Parcelable进行的初始性能测试显示,序列化速度提高了大约30%,但是Parcelable很难处理,并且似乎没有像Serialization那样处理循环对象引用,而且它仍然会暂停几秒钟,所以当我尝试其他事情的时候,我已经把这个实验放在了后面。

然后我尝试将对象树直接移动到Application类中。 每个活动只需在应用程序需要时直接从应用程序获取树。 这使得性能非常活泼,但是处理诸如意外活动开始/停止之类的极端情况(由于活动崩溃或者因为活动暂时关闭以使更多内存可用,或者其他原因)似乎很棘手。 也许它只不过是实现onSaveInstanceState() ,我不确定,但解决方案似乎有点hacky所以我还没有进一步调查。

因此,为了寻找一个不那么拼凑的解决方案,我尝试创建一个自定义的ContentProvider来存储和检索我的对象。 由于ContentProviders可以配置为使用multiprocess=true在进程中运行,我认为这是一种避免序列化成本的好方法,同时做一些比在Application对象中存储数据更“标准”的东西。 但是,ContentProviders显然不是为了返回任意对象types – 它们只支持数字,字符串,布尔值等types。看来我可以通过使用ContentResolver.getContentProviderClient().getLocalContentProvider()来存储任意对象ContentResolver.getContentProviderClient().getLocalContentProvider()直接访问我的自定义类,但我不确定这比在Application对象中存储数据要少。

当然有人必须有一个很好的解决方案来解决这个问题。 我究竟做错了什么?

除了fiXedd的解决方案,另一个是使用本地服务。 让服务“拥有”对象,通过调用服务API的活动来获取它需要的任何东西。 该服务还可以负责获取和解析数据,封装该逻辑。

Application对象是Android组件的“红头步子”。 核心Android团队的成员已经反对创建自定义Application子类的做法,尽管API肯定支持它。 设计了一个利用自定义Application子类的ADC2 200应用Application ,我可以说我应该在我的情况下使用服务。 活到老,学到老…

通过使用本地绑定模式,您的服务将根据需要自动创建和销毁,因此您不必担心这一点。 并且,根据定义,本地服务在与您的活动相同的进程/ VM中运行,因此您不必像在ContentProvider方案中那样担心编组开销。

我在我的一个应用程序中处理此问题的方法是下载数据然后将其推送到数据库中。 这样我就不必携带所有这些对象(其中,IIRC,每个只用于对象实例化大约1kb),我可以轻松地提取我需要的数据。 我不知道这是否适合你,但它对我的用例有用。

另一种方法是将数据对象保存到共享首选项文件。 这就是我们实现其中一个应用程序的方式,但我不喜欢这种方法,因为它似乎太慢了。

这是糟糕的编码实践,但最快的方法可能是使用服务来解析数据并将数据保存到静态类中,您可以在应用程序的剩余时间内使用该类。