2013-09-27 23 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);