2013-09-27 22 views
2

我在我的應用程序中使用了MapView v2(不是MapFragment),它導致內存泄漏。當我將Activity上下文傳遞給MapView構造函數時發生泄漏。如果我通過應用上下文的MapView的構造函數的內存泄漏消失了,但是的MapView開始執行不好,當我滾動了滾動它在Android MapView v2上下文問題和內存泄漏

這裏就是泄漏正在發生的快照:

enter image description here

MapView相關的代碼是:

public class MapView extends android.widget.FrameLayout { 
    private final com.google.android.gms.maps.MapView.b gD; 

    static class b extends com.google.android.gms.dynamic.a<com.google.android.gms.maps.MapView.a> { 
    private final android.content.Context mContext; 
    // Here's the Context MapView is leaking 

    } 

    static class a implements com.google.android.gms.dynamic.LifecycleDelegate { 
    // More stuff in here 
    } 
} 

我一直在MapView搞亂了幾個星期,現在的努力得到它在一個正確行爲,無濟於事。我即將放棄它。

此外,最近添加的snapshot()方法不是一個選項,因爲我已經嘗試過了,它不提供地圖的可靠快照。我對這個here和另一個相關的開放問題herehere有一個未解答的問題,所有這些問題都沒有得到回答。

回答

2

我一直在搞亂MapView幾個星期,現在試圖讓它在ScrollView中正常運行,但都無濟於事。我即將放棄它。

老實說,這是最好的。 MapView可能永遠不會在ScrollView中發揮出色。當使用這種組合時,會出現大量的錯誤;垂直滯後,通過ActionBar的MapView渲染,垂直滾動根本無法工作等等。移除ScrollView不僅是首選,而且很可能是必需的。

這就是說,如果你絕對必須做到這一點,因爲例如客戶端的限制,你有兩個選擇。

  1. 您可以使用Snapshot &的SnapshotReady回調;當回調被觸發時,將MapView替換爲快照的ImageView。你失去了交互性,但你也失去了你遇到的問題。 (你聲稱這不起作用或繪製不完整的位圖,雖然我沒有遇到這個問題,我不知道你是如何實現它的。)

  2. 寫一個自定義的類擴展MapView,覆蓋onTouchEvent以及需要修復的任何動作事件(可能爲ACTION_DOWNACTION_UP),請手動控制父級(ScrollView)是否可以攔截該操作。根據您的情況使用類似this.getParent().requestDisallowInterceptTouchEvent(true|false)的東西。請查看Android docs瞭解有關該方法的更多信息。

我希望幫助!

+0

1.繪製了一個不完整的位圖,因爲我不會立即創建MapView,我必須等待Loader完成一些數據才能構建一個自定義View,其中包含我的MapView。我試着打電話與聽衆快照後,我建立一個與選擇等,但的MapView當聽衆被激發的MapView還沒有完成渲染地圖呢,所以你會看到隨機0%至渲染地圖100%通過回調傳回的位圖。 –

+0

不知道你怎麼做,但你不應該要求一個快照前,您的MapView已經完成渲染。隨意創作一篇新文章,我可以嘗試通過它來幫助你。 –

+0

這是問題的癥結所在,當地圖完成渲染時,沒有回調可以告訴你。看起來,快照方法是意味着從按鈕按下或什麼東西觸發。 –

2

在我工作的項目中,我們遇到了類似的問題。我們在viewholder內使用mapView。解決方法是在mapview上調用onPause然後onDestroy。之後,沒有觀察到內存泄漏。

+0

我一直在尋找這對過去的4小時... ... –

3

可能與danielgomezrico's answer有關,有一個confirmed bugMapView我的位置層有關,它會泄漏內存。

的解決方法是,以確保您使用GoogleMap.setMyLocationEnabled(false)禁用我的位置在地圖被破壞之前。另外請確保調用其他地圖視圖的生命週期方法。

private MapView mMapView; 
private GoogleMap mMap; 

... 

@Override 
public void onResume() { 
    super.onResume(); 
    mMapView.onResume(); 
} 

@Override 
public void onSaveInstanceState(Bundle outState) { 
    super.onSaveInstanceState(outState); 
    mMapView.onSaveInstanceState(outState); 
} 

@Override 
public void onPause() { 
    super.onPause(); 
    mMapView.onPause(); 
} 

@Override 
public void onLowMemory() { 
    super.onLowMemory(); 
    mMapView.onLowMemory(); 
} 

@Override 
public void onDestroy() { 
    super.onDestroy(); 
    if (mMap != null) { 
     mMap.setMyLocationEnabled(false); 
    } 
    mMapView.onDestroy(); 
} 
+0

這是解決方案,我 –

0

雖然我更喜歡使用GoogleMap.setMyLocationEnabled(),它沒有我的情況下工作,所以我決定嘗試製作mContext空的,它的工作:

// Make sure to use View, not MapView 
Field contextField = View.class.getDeclaredField("mContext"); 
contextField.setAccessible(true); 
contextField.set(mapView, null);