14

背景:

  • 开发使用 Android Google Map v2 的原生 Android 应用程序,使用android.support.v4.app.FragmentActivity. 在安卓 v2.2 上运行。

客观的:

  • 在更改手机方向之前,在地图上保留“绘制”的标记/多段线。

问题):

  1. 我是否可以将标记/折线“保存”为捆绑包的一部分,并通过使用适当的方法将它们保存并简单地重新显示它们,然后使用onSaveInstanceState适当的savedInstance.put..方法“恢复”它们。onCreatesavedInstanceState.get..

    在查看 Marker 的描述时,当 Google方法文档声明以下内容getID()时,我感到很困惑:Marker.getId()

    当从 Bundle 中恢复地图时,该地图上的标记也会被恢复。但是,这些标记随后将由不同的 Marker 对象表示。标记的 id 可用于在此类恢复后检索标记对象的新实例。

    谷歌文档(上面的粗体文本)听起来好像标记只是自动恢复而无需采取任何行动。那不是我的经验……也许我误解了所陈述的内容。或者,也许您必须在 Bundle 中明确保存地图?有人可以澄清这意味着什么吗?

  2. 假设我必须通过适当的方法将标记和折线显式保存到包中,savedInstance.put...我应该保存整个标记还是应该保存标记 ID 并使用标记 ID 检索标记信息以重新显示标记?我找不到put可以让我保存整个标记的方法。

    我注意到Google Maps Android API v2的MapFragment部分说明了以下内容:

    从 GoogleMap 获得的任何对象都与视图相关联。重要的是不要抓住超出视图生命周期的对象(例如标记)。否则会导致内存泄漏,因为视图无法释放。

    这个声明让我相信我不应该尝试保存标记本身,而是尝试保存标记 ID,然后根据与标记 ID 关联的标记对象重新生成标记。对于折线也是如此。我的假设正确吗?

  3. 另外,我应该避免将标记作为类变量吗?我担心的是,如果 Marker 是一个类变量并且 Activity Map 片段放置在后堆栈上,这可能会导致内存泄漏,因为它会有效地“保持对象”,如上述文档中所述。这是我应该关心的事情吗?

问候。

4

2 回答 2

14

我可以将标记/折线“保存”为捆绑包的一部分,并通过使用适当的“savedInstance.put..”方法将它们保存在 onSaveInstanceState 中重新显示它们,然后使用适当的“恢复”它们在 onCreate 中吗? savedInstanceState.get..” 方法。

不。

谷歌文档(上面的粗体文本)听起来好像标记只是自动恢复而无需采取任何行动。那不是我的经验……也许我误解了所陈述的内容。或者,也许您必须在 Bundle 中明确保存地图?有人可以澄清这意味着什么吗?

你没有误解任何东西。文档不正确。

我应该保存标记 ID 并使用标记 ID 检索标记信息以重新显示标记

标记 ID 在配置更改时不是永久性的 - 它取决于创建可视对象的顺序(第一次调用addMarker返回 ID 为“m1”的对象,第二次调用为“m2”)。您不能以任何方式使用此值(从 API 版本 3.1.36 开始),恕我直言,它的存在确实没有意义。我实际上已经总结了一个与 ID 相关的问题。至少应该有一个没有意义的功能GoogleMap.getMarkerById(String)Marker.getId()

3)另外,我应该避免将标记作为类变量吗?我担心的是,如果 Marker 是一个类变量并且 Activity Map 片段放置在后堆栈上,这可能会导致内存泄漏,因为它会有效地“保持对象”,如上述文档中所述。这是我应该关心的事情吗?

是的。保持对Marker或任何其他可视对象的静态引用会导致泄漏。


并不是说回答您所有的问题和疑虑使其更接近解决方案,所以这是我的建议。

我假设您有一个数据集,该数据集是MarkersPolylinesWeb 服务获取后创建的,并且可能将其存储在 DB 中。现在,如果您从数据库中将其加载到AsyncTask您的数据库中,Activity或者甚至不将其存储在其中DB,而只是Activity直接获取,那就太糟糕了。

尝试使您的数据尽可能可访问,因此只需在进程被终止后(或在内存不足时将其删除后)将其重新加载到内存中。如果你这样做 - 那很好。当然不是全部:如果你有 20000 个标记并且每个标记都显示在信息窗口上,它可以等待......

现在您已经拥有在内存中创建标记所需的所有数据,只需像第一次那样创建它们。不需要额外的代码。

我们可以争论这是好主意还是坏主意,我会改进答案,但这需要有关上下文的更多信息:

  • 多少个标记和折线
  • 你有什么额外的数据
  • 你把模型放在哪里
  • 等等

当然还有另一种方式:您可以发送MarkerOptions. onSaveInstanceState如果您保持最新,或者如果您Markers不更改并且没有那么多,这可能对您有用。我无法理解每次旋转时通过 IPC 发送数千个对象或按下 HOME 按钮。

于 2013-06-03T18:50:27.110 回答
14

在我看来,调用setRetainInstance(true);保存地图的片段可以通过暂停、方向更改等保留地图上的所有内容,而不必担心设置和获取。这不是推荐的方法有什么原因吗?

于 2014-02-27T04:19:48.617 回答