2013-06-03 141 views
13

背景如何最好地重新創建標記/折線:當手機被旋轉(方向改變)

  • 開發一個原生Android應用程序使用Android的谷歌地圖V2,採用android.support.v4.app.FragmentActivity。在Android v2.2上運行。

目的:

  • 在地圖上保留 「繪製」 標記/折線手機方向改變之前。

問題(S):

  1. 我可以標記/折線「保存」作爲包的一部分,只是必須使用適當的節省他們在onSaveInstanceState他們重新顯示savedInstance.put..方法,然後使用適當的savedInstanceState.get..方法在onCreate中「恢復」它們。

    在審查標記getID()說明我很困惑,當谷歌文檔Marker.getId() method狀態如下:

    地圖時從包恢復,標誌將原本地圖上也恢復。但是,這些標記將由不同的標記對象表示。標記的ID可用於在恢復之後檢索標記對象的新實例。

    谷歌文檔(上面的粗體文本)使得它聽起來像標記只是自動恢復而不必採取任何行動。那不是我的經歷......也許我錯誤地解釋了陳述內容。或者,也許你必須明確地將地圖保存在Bundle中?有人可以澄清這是什麼意思?

  2. 假設我將必須明確地通過適當的savedInstance.put...方法的標記和折線保存到束應該我保存整個標記或應保存的標記ID和使用標記ID來檢索標記信息重新顯示標記?我找不到能夠保存整個標記的put方法。

    我注意到谷歌地圖API的Android V2的MapFragment section其規定如下:

    從GoogleMap的獲得的任何物體與視圖關聯。不要堅持物體(例如標記)超出視野的生命。否則會導致內存泄漏,因爲視圖無法釋放。

    此聲明使我相信我不應該嘗試保存標記本身,而是嘗試保存標記ID,然後根據與標記ID關聯的標記對象重新生成標記。對於PolyLines也是如此。我的假設是否正確?

  3. 另外,我是否應該避免將標記作爲類變量?我擔心的是,如果Marker是一個類變量,並且Activity Map片段被放置在後端堆棧上,這可能會導致內存泄漏,因爲它將有效地「保留到對象」,如上述文檔中所述。這是我應該關心的嗎?

問候。

回答

14

我可以標記/折線「保存」作爲包的一部分,只是必須使用適當的節省他們在他們的onSaveInstanceState重新顯示「savedInstance.put ..」方法,然後選擇「恢復」他們在onCreate中使用適當的「savedInstanceState.get ..」方法。

的谷歌文檔(以上黑體字)使得它聽起來像標記的只是自動的恢復,而不必採取任何行動。那不是我的經歷......也許我錯誤地解釋了陳述內容。或者,也許你必須明確地將地圖保存在Bundle中?有人可以澄清這是什麼意思?

你不會誤解任何東西。該文檔不正確。

我應該保存標記ID和使用標記ID重新顯示標記

標記ID是不能跨越的配置更改的東西永久檢索標記信息 - 這取決於視覺序列創建對象(首先調用addMarker返回ID爲「m1」的對象,第二個爲「m2」)。你不能以任何方式使用這個值(如API版本3.1.36),恕我直言,它的存在確實沒有意義。我實際上已經登錄an issue related to ID。應該至少有一個功能GoogleMap.getMarkerById(String)Marker.getId()沒有什麼意義。

3)另外,我是否應該避免將標記作爲類變量?我擔心的是,如果Marker是一個類變量,並且Activity Map片段被放置在後端堆棧上,這可能會導致內存泄漏,因爲它將有效地「保留到對象」,如上述文檔中所述。這是我應該關心的嗎?

是的。保留對Marker或任何其他可視對象的靜態引用會導致泄漏。


不是回答你所有的問題和擔憂使它更接近解決方案,所以這裏是我的主張。

我假設你有一個數據集,其中MarkersPolylines是從Web服務中獲取並可能存儲在數據庫中。現在,如果您從ActivityAsyncTask中將數據從DB加載,或者甚至不將其存儲在DB中,但只能直接在Activity中獲取 - 這很糟糕。

儘量讓您的數據儘可能可訪問,因此只有在進程死亡後(或者在內存不足時將其放下後)才能重新加載到內存中。如果你這麼做 - 那很好。當然不是全部:如果您有20000個標記,並且每個標記的圖像都顯示在信息窗口中,則可以等待...

現在您已經擁有了在內存中創建標記所需的全部數據,只需像第一次那樣創建它們即可。無需額外的代碼。

我們可以爭論這是好還是壞主意,我會改進的答案,但是這需要有關上下文的詳細信息:

  • 多少標記和折線
  • 你有什麼額外的數據
  • 你在哪裏保存你的模型

當然還有另一種方法:你可以發送MarkerOptions in onSaveInstanceState。如果你保持它的最新狀態或者你的Markers沒有改變,並且沒有那麼多,這可能對你有用。每次旋轉或按HOME按鈕都無法通過IPC發送數千個對象。

+0

謝謝梅西......只是澄清一下可以做什麼和不可以做什麼是非常有幫助的。希望有人針對Google文檔提交了一個問題。 – user2101068

+0

作爲背景......我只有一個標記,我在這裏擔心,兩條多段線連接到這個標記。標記代表用戶在屏幕上點擊的位置(tapMarker)。第一條多段線將用戶當前的GPS連接連接到tapMarker,第二條多段線將點擊標記連接到指定的LatLng。指定的LatLng的數據將存儲在數據庫中。 – user2101068

+0

在這種情況下,您只需在'onSaveInstanceState'中發送'LatLng'。這是有道理的,因爲它是用戶活動(就像編輯文本字段一樣)。可選擇兩個'ArrayList '重新創建折線。我認爲我的答案會更有用;) –

11

在我看來,在保存地圖的片段上調用setRetainInstance(true);可以通過暫停,方向更改等保留地圖上的所有內容,而無需擔心設置和獲取。有沒有理由不推薦這種方法?

+0

我可以確認它工作正常!就這麼簡單。爲什麼這個帖子沒有標記爲答案? –

+0

對於一個它不起作用,如果你的地圖片段嵌套在另一個片段內。你會得到一個運行時異常。 –

+0

那麼如果你在兩個碎片上設置了RainainInstance會發生什麼? (對不起,遠離測試環境,但仍然好奇) – lucas