星期一, 6月 25, 2012

MapView in multiple activities

在開發Android App時,可以非常簡便的來開發與使用地圖,

只要import com.google.android.maps 當中的相關元件就可以了開心使用,

但因為MapView是很耗記憶體的元件,

因此Google在設計MapView時,將MapView設計成

所有使用到MapView的Activity會參考到同一個MapView資源,

使用同一塊快取記憶體,以避免大量的記憶體使用造成的Memory leak。

所以在你所開發的程式中,所使用多個MapView其實都參照到同一個

不同只在於你在MapView上所加的Overlay不同、控制器不同、zoom等參數不同而已。

原本立意良善的設計,有時卻會帶來意外的困擾,

在Navier HUD當中使用到MapView的Activity目前有兩個,

一個是使用者可以在地圖上點選建立目的地的地圖,













另一個是顯示搜尋結果的地圖,







在舊的版本中(v1.3.1及之前)當您搜尋一個地點進入搜尋結果後,

在以back鍵回到目的地地圖時,

這時拖拉地圖,會發現地圖下方有一點不正常的顯示情況(地圖閃爍且看到背景)

原本應該是填滿地圖的畫面,在拖拉時變得顯示不正常了。

經過一天一夜爬文,可以確定造成此錯誤的原因就是,

雖然在兩個Activity當中引用兩個MapView,

但是因為兩個Activity當中的排版有些許差異,

因此在回到第一個畫面時還帶著第二個畫面的MapView排版屬性。

這裡複習一下Activity的生命週期,當由第一個Activity進入第二個Acitivity時,

第一個Activity會呼叫OnPause(),並將Activity放置在Activity Stack當中,

直到由第二個Activity返回時,

由Stack中取回狀態並呼叫OnResume()回到第一個Activity。

而通常我們會把設定畫面layout的程式碼setContentView()擺在onCreate()當中,

所以在OnResume()時並不會重新讀取MapView的Layout,

因為共用MapView的關係,回到畫面1時還帶著畫面2的Layout參數,

而造成畫面看起來不正常。直到使用者用兩指縮放地圖後才會正常。

解決這個問題最快的方式可以將兩個Activity的MapView長寬都設成match_parent,

但這樣設在Navier HUD會造成畫面2的FlipView處理OnFling()異常,

可能要修改排版方式才能解決Orz,

但最後終於自己試出一個最快最方便的解決方式,

連排版都不用變更,

就是在畫面1的OnResume()時,將MapView的visibility設為GONE,

然後再設回VISIBLE,地圖就會重新處理Layout,

結果就正常顯示了。


mapView.setVisibility(View.GONE);
mapView.setVisibility(View.VISIBLE);



此錯誤會在下次更新時修正(v1.3.2)

張貼留言