背景:
- 使用
android.support.v4.app.FragmentActivity
开发使用Android Google Map v2的本地Android应用程序。在Android v2.2上运行
目标:
- 在更改手机方向之前,保留地图上"绘制"的标记/多段线
问题:
-
我可以将标记/多段线"保存"为束的一部分,然后使用适当的
savedInstance.put..
方法将其保存在onSaveInstanceState
中,然后使用相应的savedInstanceState.get..
方法将其"恢复"到onCreate
中,从而简单地重新显示它们吗。在查看Marker
getID()
的描述时,当Marker.getId()
方法的Google文档指出以下内容时,我感到困惑:当从Bundle恢复贴图时,该贴图上的标记也会恢复。但是,这些标记将由不同的Marker对象表示。在这样的恢复之后,标记的id可以用于检索marker对象的新实例。
谷歌文档(上面的粗体文本(听起来像是标记的自动恢复,而不需要采取任何行动。这不是我的经验。。。也许我误解了所说的话。或者,您可能必须明确地将地图保存在捆绑包中?有人能澄清一下这意味着什么吗?
-
假设我必须通过适当的
savedInstance.put...
方法将标记和多段线显式保存到束中,我应该保存整个标记,还是应该保存标记id并使用标记id检索标记信息以重新显示标记?我找不到允许我保存整个Marker的put
方法。我注意到Google Maps Android API v2的
MapFragment
部分声明如下:从GoogleMap中获得的任何对象都与视图相关联。重要的是不要抓住视图生命之外的对象(例如Marker(。否则,它将导致内存泄漏,因为视图无法释放。
这句话让我相信,我不应该尝试保存Marker本身,而是应该尝试保存标记id,然后根据与标记id关联的标记对象重新生成标记。PolyLines也是如此。我的假设正确吗?
-
此外,我应该避免将Marker作为类变量吗?我担心的是,如果Marker是一个类变量,而Activity Map片段被放在后堆栈上,这可能会导致内存泄漏,因为它将有效地"抓住对象",如前面提到的文档所述。这是我应该关心的事情吗?
谨致问候。
我可以将标记/多段线"保存"为捆绑包的一部分,然后使用适当的"savedInstance.put.."方法将它们保存在onSaveInstanceState中,然后在onCreate中"还原"它们,从而重新显示它们吗。
没有。
谷歌文档(上面的粗体文本(听起来像是标记的自动恢复,而不需要采取任何行动。这不是我的经验。。。也许我误解了所说的话。或者,您可能必须明确地将地图保存在捆绑包中?有人能澄清一下这意味着什么吗?
你没有误解任何东西。文档不正确。
我应该保存标记ID并使用标记ID检索标记信息以重新显示标记吗
标记ID在配置更改中不是永久性的——它取决于视觉对象创建的顺序(第一次调用addMarker
返回ID为"m1"的对象,第二次调用ID为"m2"(。您不能以任何方式使用此值(从API版本3.1.36开始(,IMHO的存在实际上没有意义。实际上,我已经总结了一个与ID有关的问题。Marker.getId()
至少应该有一个函数GoogleMap.getMarkerById(String)
,这样才没有什么意义。
3( 此外,我应该避免将Marker作为Class变量吗?我担心的是,如果Marker是一个类变量,而Activity Map片段被放在后堆栈上,这可能会导致内存泄漏,因为它将有效地"抓住对象",如前面提到的文档所述。这是我应该关心的事情吗?
是的。保持对Marker
或任何其他视觉对象的静态引用会导致泄漏。
并不是说回答你所有的问题和担忧使它更接近解决方案,所以以下是我的建议。
我假设您有一个从中创建Markers
和Polylines
的数据集,并可能在从webservice获取后将其存储在DB中。现在,如果您在Activity
的AsyncTask
中从DB加载它,或者甚至不将它存储在DB
中,而是直接在Activity
中获取它,那就太糟糕了。
尽量使您的数据可访问,这样它只需要在进程终止后(或在内存不足时将其丢弃后(重新加载到内存中。如果你这样做,那就太好了。当然不是全部:如果你有20000个标记,每个标记的图像都显示在信息窗口上,它可以等待。。。
现在您已经拥有了在内存中创建标记所需的所有数据,只需像第一次一样创建它们即可。不需要额外的代码。
我们可以争论这个想法是好是坏,我会改进答案,但这需要更多关于上下文的信息:
- 有多少标记和多段线
- 你还有什么额外的数据
- 你的模型放在哪里
- 等等
当然还有另一种方式:您可以在onSaveInstanceState
中发送MarkerOptions
。如果你让它保持最新,或者如果你的Markers
没有改变,并且没有那么多,这可能对你有用。每次旋转或按下HOME按钮时,我都无法通过IPC发送数千个对象。
在我看来,在保存地图的片段上调用setRetainInstance(true);
可以通过暂停、方向更改等方式保留地图上的所有内容,而不必担心设置和获取。这不是推荐的方法有什么原因吗?