Android MapView v2上下文问题和内存泄漏

时间:2013-09-27 23:16:54

标签: android android-maps-v2

我在我的应用程序中使用MapView v2(而不是MapFragment)并且它导致内存泄漏。当我将Activity上下文传递给MapView构造函数时发生泄漏。如果我将应用程序上下文传递给MapView构造函数,则内存泄漏会消失,但是当我滚动ScrollView时,MapView会开始表现不佳。

以下是泄漏发生地点的快照:

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几周,试图让它在ScrollView中正常运行,但无济于事。我即将放弃它。

此外,最近添加的snapshot()方法不是一个选项,因为我已经尝试过它,并且它没有提供可靠的地图快照。我对此here以及另一个相关的未决问题herehere提出了一个未解决的问题,所有这些问题都没有得到解答。

4 个答案:

答案 0 :(得分:3)

可能与danielgomezrico's answer相关,MapView中与我的位置图层相关的confirmed bug泄漏了内存。

解决方法是确保在销毁地图之前使用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();
}

答案 1 :(得分:2)

  

我已经在使用MapView几周了,试图让它在ScrollView中正常运行,但无济于事。我即将放弃它。

老实说,这是最好的。 MapView很可能永远不会在ScrollView中发挥出色。使用这种组合时会出现许多错误;垂直延迟,ActionBar上的MapView渲染,垂直滚动无法正常工作等。删除ScrollView不仅是首选,而且很可能是必需的。

也就是说,如果您绝对必须这样做,例如,由于客户端限制,您有两种选择。

  1. 您可以使用Snapshot&amp; SnapshotReady回调;触发回调时,将MapView替换为快照的ImageView。你失去了互动性,但你也失去了你遇到的问题。 (您声称这不起作用或绘制不完整的位图,但我没有遇到过这个问题。我不确定您是如何实现它的。)

  2. 编写一个扩展MapView的自定义类,覆盖onTouchEvent以及需要修复的任何运动事件(可能是ACTION_DOWNACTION_UP),手动控制是否为父(ScrollView) )可以拦截行动。根据您的情况使用this.getParent().requestDisallowInterceptTouchEvent(true|false)之类的内容。有关该方法的详细信息,请查看Android docs

  3. 我希望有所帮助!

答案 2 :(得分:2)

在我工作的项目中,我们遇到了类似的问题。我们在viewholder里面使用了mapView。解决方案是在mapview上调用onPause然后调用onDestroy。之后没有观察到内存泄漏。

答案 3 :(得分:2)

你是在片段中使用它吗?可能与此错误相关https://code.google.com/p/android/issues/detail?id=185902