4

在 Google Maps API v2 中管理标记的正确方法是什么?我正在尝试仅使用该区域内可见的标记来更新视口,并且我正在使用OnCameraChangeListener它来了解何时使用最新标记更新视口。但是,看起来地图在绘制或更新标记时是不可滚动/可缩放的。我注意到在setIcon()使用时,滞后更严重。在 Google Maps v1 中,我在使用 ItemizedOverlays 时从未遇到过这个问题。这是我的代码在滚动/缩放中遇到滞后的要点:

private void updatePinsOnMap(MapDisplayData mapDisplayData) {
    BitmapDescriptor bitmapDescriptor = BitmapDescriptorFactory.fromBitmap(getPinWithBadgeCount(2));
    List<LatLng> latlngs = Lists.newArrayList();
    for (NearbyPlaceEdge place : mapDisplayData.getPlaces()) {
        latlngs.add(place.latlng);
    }
    for (NearbyPlaceCluster cluster : mapDisplayData.getClusters()) {
        latlngs.add(cluster.latlng);
    }
    int numMarkersToPlot = latlngs.size();
    for (int i = 0; i < numMarkersToPlot; i++) {
        if (i < mMarkers.size()) {
            // recycle
            mMarkers.get(i).setPosition(latlngs.get(i));
        } else {
            final Marker m = mGoogleMap.addMarker(
                new MarkerOptions()
                    .position(latlngs.get(i))
                    .icon(bitmapDescriptor)
            );
            mMarkers.add(m);
        }
    }
    for (int i = mMarkers.size() - 1; i >= numMarkersToPlot; i--) {
        mMarkers.remove(i).remove();
    }
}

更新:

我用上面的代码创建了一个示例应用程序,事情按计划工作(即没有滞后)。我花了一些时间思考这个问题,我相信这与 Google Maps v2 所需的内存有关。从查看 logcat 来看,每次我移动地图(触发地图更新)时,我都会在 Nexus 4 上收到很多这样的 gc 消息

05-27 14:28:23.701: D/dalvikvm(2849): GC_FOR_ALLOC freed 1198K, 23% free 26889K/34504K, paused 112ms, total 112ms

这是 API 中潜在的内存泄漏吗?我现有的应用程序已经占用了一些内存,但我认为 GMaps 将能够根据可用的内存适当地管理自己的内存。

4

1 回答 1

1

看起来您对 API 进行了太多调用。

对 setPosition、remove 和 addMarker 的每次调用都在执行 IPC。如果可能,我建议将其限制为低于 100。

从代码中我看到你正在做某种聚类,这是一个好的开始。

我还建议不要为超出屏幕的标记调用 remove(除非必要,例如由于缩放更改而更改群集)并保持标记的身份,因此不会重新定位或以其他方式修改留在屏幕上的标记。

使用Android Maps Extensions集群引擎时,我对 20000 个标记没有任何问题,这就是我所描述的。

问题更新后更新:

现在是一个不同的故事。您的应用程序使用了大约 25 MB。这对于 Maps API v2 来说是有问题的,因为每个调用(就像我之前所说的)都在执行 IPC,这反过来又根据这个答案和其他来源强制 GC。堆越大意味着 GC 所需的时间越多。

解决方案?最好将内存占用保持得更低。

于 2013-05-27T06:24:54.997 回答