簡體   English   中英

Android - 谷歌地圖卡住了

[英]Android - google maps gets stuck

我正在開發一個顯示谷歌 map 和一堆標記的應用程序。 有很多標記,所以我將它們分成較小的組並僅顯示那些,這些標記在某些范圍內,具體取決於相機的當前 position。

為此,我正在使用GoogleMap.OnCameraIdleListener 首先我移除監聽器,進行計算和繪圖,然后將監聽器恢復到包含我的 map 的片段:

@Override
public void onCameraIdle() {
    mMap.setOnCameraIdleListener(null);

    clearMap();
    findTheMarkersInBounds();
    displayTheMarkers();

    mMap.setOnCameraIdleListener(this);
}

這樣我只繪制我需要顯示的標記,並且性能比在 map 上同時擁有 1000 個標記要好得多。 我也畫了大約相同數量的折線,但這不是重點。

由於一些奇怪的原因,經過一些平移和縮放后,地圖不再響應。 不能縮放也不能平移。 應用程序顯示一個沒有響應的對話框,我應該等待或關閉應用程序。 logcat 中不顯示任何錯誤。 我無法准確判斷何時會發生這種情況。 有時在第一個鍋之后,有時我可以移動 2-3 分鍾左右。 同樣的事情發生在模擬器和物理設備上。

有沒有人經歷過這樣的事情? 謝謝? 或者我是以錯誤的方式接近這個。 我還應該如何優化 map 以顯示大約 1000 個標記和折線,(標記上有文字,所以它不能是相同的 Bitmap 並且所有折線都可以有不同的 Z62848E3CE58204AA985513A7 可以點擊'不要將它們組合成一條大折線)

編輯。 關於我的方法的更多信息:

從內部數據庫加載所有標記位置后,我對所有標記位置進行循環,並基於它們的 position 並將它們放置到相應的區域。 它是一個二維列表數組。

我的整個區域被划分為 32x32 個較小的矩形區域。 當我搜索要顯示的標記時,我會確定哪個區域在視圖中並僅顯示位於該區域中的那些標記。 這樣我就不需要遍歷所有的標記。

我的方法(非常簡化)如下所示:

ArrayList<MarkerObject> markersToDisplay = new ArrayList<MarkerObject>();

private void findTheMarkersInBounds() {
    markersToDisplay.clear();
    LatLngBounds bounds = mMap.getProjection().getVisibleRegion().latLngBounds;
    int[] regionCoordinates = getRegionCoordinates(bounds); // i, j coordinates of my regions [0..31][0..31]
    markersToDisplay.addAll(subdividedMarkers[regionCoordinates[0]][regionCoordinates[1]]);
}

private void drawMarkers() {
    if ((markersToDisplay != null) && (markersToDisplay.size() > 0)) {
        for (int i=0; i<markersToDisplay.size(); i++) {
            MarkerObject mo = markersToDisplay.get(i);
            LatLng position = new LatLng(mo.gpsLat, mo.gpsLon);
            BitmapDescriptor bitmapDescriptor = BitmapDescriptorFactory.fromBitmap(createMarker(getContext(), mo.title));
            GroundOverlay m = mMap.addGroundOverlay(groundOverlayOptions.image(bitmapDescriptor).position(position, 75));
            m.setClickable(true);
        }
    }
}

如果沒有findTheMarkersInBounds()displayTheMarkers()的源代碼,很難為您提供幫助,但似乎您需要不同的方法來提高性能,例如:

  1. 如果可能的話,改進你的findTheMarkersInBounds()邏輯;

  2. 在單獨的線程中運行findTheMarkersInBounds()並在findTheMarkersInBounds()搜索期間不顯示所有標記,而是一個接一個(或一次顯示 10..20 個);

  3. 如果可能的話,改進你的displayTheMarkers() ,實際上可能是在 canvas 上使用自定義繪圖(就像在這個答案中一樣),而不是創建數千個Marker對象。

對於問題更新:

小的改進(首先,因為它們用於 main):

  1. markersToDisplay的最大大小作為構造函數參數傳遞: ArrayList<MarkerObject> markersToDisplay = new ArrayList<MarkerObject>(1000);

  2. 代替for (int i=0; i<markersToDisplay.size(); i++) {

for (MarkerObject mo: markersToDisplay) {

  1. 不要每次都創建LatLng position ,創建一次並存儲在MarkerObject字段中。

主要改進:

此行是問題的根源:

BitmapDescriptor bitmapDescriptor = BitmapDescriptorFactory.fromBitmap(createMarker(getContext(), mo.title));
GroundOverlay m = mMap.addGroundOverlay(groundOverlayOptions.image(bitmapDescriptor).position(position, 75));

恕我直言,使用地面覆蓋顯示數千個標記是個壞主意。 Ground Overlay 用於顯示默認 Google Map 的多個“用戶”地圖(如公園或動物園詳細信息的本地計划)。 使用 canvas 上的自定義繪圖,如上面的鏈接。 但是如果您決定使用地面疊加層 - 不要每次都重新創建它們:創建一次,在MarkerObject中存儲對它們的引用並重用:

// once when marker created (just example)
mo.overlayOptions = new GroundOverlayOptions()
.image(BitmapDescriptorFactory.fromBitmap(createMarker(getContext(), mo.title)))
.position(mo.position, 75))
.setClickable(true);

...
// in your drawMarkers() - just add:
... 
for (MarkerObject mo: markersToDisplay) {
    if (mo.overlayOptions == null) {
        mo.overlayOptions = createOverlayOptionsForThisMarker();
    }
    mMap.addGroundOverlay(mo.overlayOptions)
}

但是恕我直言 - 完全擺脫成千上萬的地面覆蓋 - 在 canvas 上使用自定義繪圖。

在與谷歌地圖 android 技術支持進一步調查和溝通后,我們找到了解決方案。 GroundOverlay.setZIndex() 方法中有一個錯誤。

您所要做的就是更新到最新的 API 版本。 Google Maps SDK v3.1 中不再存在該錯誤。

目前它處於測試階段,但遷移非常簡單。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM