【问题标题】:The best way to pass array of objects to the activity (or view)?将对象数组传递给活动(或视图)的最佳方式?
【发布时间】:2017-12-31 15:04:59
【问题描述】:

我正在寻找一种将对象数组传递给我的活动/片段的方法。我想到的第一件事是使对象 Parcelable,然后将其作为列表传递到 Intent 中。但是,Parcelable 概念主要设计用于跨流程边界,例如,当您想要启动新活动或发送广播时。这就是为什么还建议在意图中保持较小的事物大小(最好是几 KB),因为每个进程都有自己的私有绑定器事务缓冲区以在操作系统级别使用。

我的第一个问题是,您认为我在上述论点中可能遗漏了一些观点吗?

其次,当我使用 LocalBroadcastManager 发送广播时,intent 中的数据是否仍会下降到操作系统级别以进行编组/解组并传递回进程?如果不是,则传递相对较大的数组可能更有意义,因为它不会代表我的进程占用操作系统内存中的任何共享空间(假设使用 LocalBraodcastManager 时数据不会离开我的应用程序)。

希望清楚!

【问题讨论】:

  • 你指的这个巨大的数组是什么?您是否可以不考虑将其存储到数据库中并将其提取到即将到来的活动中,因为您只需要传递一个轻量级密钥。
  • 当然可以,但数据资源/提供者不是我的意思。假设您有一个方法 getItems()。一种选择是您可以传递一个侦听器并在数据准备好时调用相关的回调。另一个是 - 如果您不想真正想要依赖任何类型的侦听器接口,或者想要非常异步 - 侦听(广播)事件,在该事件中返回数据是有意图的。跨度>

标签: android android-intent arraylist parcelable


【解决方案1】:

如果您有很多对象,那么在将它们从应用程序的一个组件发送到另一个组件时,对它们进行序列化和反序列化(打包和解包)就没有意义了。假设您的应用程序的所有组件都位于同一个操作系统进程中(这是默认行为),您可以通过将这些对象放入 static 成员变量中来共享这些对象。示例见https://stackoverflow.com/a/10909959/769265。

这种方法有缺点。如果 Android 杀死你的进程,当用户返回应用程序时,static 成员变量可能尚未设置。您需要处理这种情况并采取相应措施。

其他处理大型对象(或大型对象数组)的方法有:

  • 存储在SharedPreferences(您需要将对象序列化为字节流以将其保存在SharedPreferences)
  • 存储在 SQLite 数据库中(您可以使用自定义架构并根据需要高效或低效地存储数据)
  • 存储在文件中(您可以将数据序列化为字节流并写入文件,也可以使用 Java 提供的方法将“对象”写入文件)

【讨论】:

  • 感谢大卫的意见。使用“静态”似乎是一种选择。除此之外,我更好奇的是如何将这个对象列表传递给上层(在我们的例子中是 ui)而不是如何提供它(可能是通过共享首选项、数据库、文件或其他)。
  • 我不明白你所说的“通过”是什么意思。如果您的 UI (Activity) 和其他组件 (BroadcastReceiver 或 Service) 在同一个 OS 进程中运行(这是默认设置),则无需“通过它”。您只需将它放在 static 变量中,其他类就可以从那里引用它。
  • 其实,你没看错。通过“传递”,我只是指使用(最好)android方式并以解耦方式将相关结果/数据从核心转发到ui。正如您所建议的,使用静态是一种方法,但似乎不是最好的设计?如果你看我问题的第二部分,这就是为什么问我们是否仍然可以通过使用 LocalBroadcastManager 来利用意图。
  • 我假设(因为我没有查看代码或自己尝试过)即使使用LocalBroadcastManager,对象仍将被序列化和反序列化(编组/解组)。 LocalBroadcastManager 与发送常规广播 Intent 唯一不同的是它不需要使用 IPC 来(可能)将广播发送到其他进程。
  • 这更有趣。如果它不需要 IPC,那么为什么我还需要编组/解组事物,因为我没有退出我的流程。除此之外,这也可能意味着我可以传递(相对)大量对象,因为我没有进入操作系统级别。
【解决方案2】:

使用bundle object,它使用字符串key-object配置,非常好用

【讨论】:

  • 它可能很容易使用,但它不能承载大量数据。
  • 你必须传递什么类型的数据?
  • 假设它是一个自定义对象数组,每个对象有 100 个字段。但关键是如何将此捆绑包传递给您的活动?
  • 我不太了解您的问题...如果您希望代码在第一个活动中 Intent intent = new Intent(this,YourClass.class); intent.putExtra(name, array[]) startActivity(intent);并在第二个 int[] array = intent.getIntArrayExtra(name);
  • @AlbertoSinigaglia 这就是我问题的重点。当然,您可以通过意图传递它,但问题是意图并非旨在用于跨组件传递大量对象。
猜你喜欢
  • 1970-01-01
  • 2016-06-14
  • 1970-01-01
  • 2017-09-16
  • 1970-01-01
  • 2021-03-09
  • 2023-03-03
  • 1970-01-01
  • 2014-07-18
相关资源
最近更新 更多