【问题标题】:Android MapView v2 Context Issues and Memory LeakAndroid MapView v2 上下文问题和内存泄漏
【发布时间】:2013-09-27 23:16:53
【问题描述】:

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

这是泄漏发生位置的快照:

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,所有这些都没有得到回答。

【问题讨论】:

    标签: android android-maps-v2


    【解决方案1】:

    可能与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();
    }
    

    【讨论】:

    • 这是我的解决方案
    【解决方案2】:

    我已经用 MapView 搞砸了几个星期,现在试图让它在 ScrollView 中正常运行,但无济于事。我要放弃了。

    老实说,这是最好的。 MapView 可能永远不会在 ScrollView 中发挥出色。使用这种组合时会出现许多错误。垂直滞后、MapView 在 ActionBar 上的渲染、垂直滚动根本不起作用等。移除 ScrollView 不仅是首选,而且很可能是必需的。

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

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

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

    希望对你有帮助!

    【讨论】:

    • 1.它绘制了一个不完整的位图,因为我没有立即创建 MapView,我必须等待加载器完成一些数据来构建一个包含我的 MapView 的自定义视图。在使用选项等构建 MapView 后,我尝试使用侦听器调用快照,但是当触发侦听器时,MapView 尚未完成地图的渲染,因此您会随机看到 0% 到 100% 的地图呈现在由回调传回的位图。
    • 不确定你是怎么做的,但你不应该在 MapView 完成渲染之前调用快照。随意发一个新帖子,我可以帮助你完成它。
    • 这是问题的症结所在,地图何时完成渲染没有回调告诉你。似乎快照方法是通过按下按钮或其他方式触发的。
    • 有机会告诉您的客户“不,您不能对此感到抱歉。这在技术上是不可能/不可取的”,这总是一件好事。我当然愿意。
    【解决方案3】:

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

    【讨论】:

      【解决方案4】:

      您是否在片段中使用它?可能和这个bug有关https://code.google.com/p/android/issues/detail?id=185902

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2015-10-21
        • 2019-08-16
        • 2023-03-22
        • 2014-08-27
        • 1970-01-01
        • 2012-12-19
        • 2013-01-09
        • 1970-01-01
        相关资源
        最近更新 更多