From bda0e94af2a6f6ddb7e61f2aecdf6a50479a6b32 Mon Sep 17 00:00:00 2001 From: Tobrun Date: Mon, 17 Oct 2016 14:50:09 +0200 Subject: [PATCH] MarkerView more robust when updates are asynchronous (#6717) * [android] - remove ViewMarkers crash, show correct view cache size in test activity * use MapboxMap to indicate a MarkerView is no longer added on a map, no future updates will be passed on to core. * resolve memory leak --- .../mapboxsdk/annotations/MarkerView.java | 14 +++++++---- .../annotations/MarkerViewManager.java | 23 ++++++++----------- .../annotation/MarkerViewActivity.java | 3 ++- 3 files changed, 21 insertions(+), 19 deletions(-) diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/MarkerView.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/MarkerView.java index 5c84fb999..b41eebff0 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/MarkerView.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/MarkerView.java @@ -345,19 +345,23 @@ public class MarkerView extends Marker { *

* This method is used to instantiate the MarkerView and provide an instance of {@link com.mapbox.mapboxsdk.maps.MapboxMap.MarkerViewAdapter} *

+ *

+ * This method is used to notify that a MarkerView is no longer active by setting a null value. + *

* * @param mapboxMap the MapboxMap instances */ @Override public void setMapboxMap(MapboxMap mapboxMap) { super.setMapboxMap(mapboxMap); + if(mapboxMap!=null) { + if (isFlat()) { + // initial tilt value if MapboxMap is started with a tilt attribute + tiltValue = (float) mapboxMap.getCameraPosition().tilt; + } - if (isFlat()) { - // initial tilt value if MapboxMap is started with a tilt attribute - tiltValue = (float) mapboxMap.getCameraPosition().tilt; + markerViewManager = mapboxMap.getMarkerViewManager(); } - - markerViewManager = mapboxMap.getMarkerViewManager(); } /** diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/MarkerViewManager.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/MarkerViewManager.java index fe1a48993..ded313071 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/MarkerViewManager.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/annotations/MarkerViewManager.java @@ -317,6 +317,7 @@ public class MarkerViewManager { } } } + marker.setMapboxMap(null); markerViewMap.remove(marker); } @@ -390,14 +391,15 @@ public class MarkerViewManager { // remove old markers Iterator iterator = markerViewMap.keySet().iterator(); while (iterator.hasNext()) { - MarkerView m = iterator.next(); - if (!markers.contains(m)) { + MarkerView marker = iterator.next(); + if (!markers.contains(marker)) { // remove marker - convertView = markerViewMap.get(m); + convertView = markerViewMap.get(marker); for (MapboxMap.MarkerViewAdapter adapter : markerViewAdapters) { - if (adapter.getMarkerClass().equals(m.getClass())) { - adapter.prepareViewForReuse(m, convertView); + if (adapter.getMarkerClass().equals(marker.getClass())) { + adapter.prepareViewForReuse(marker, convertView); adapter.releaseView(convertView); + marker.setMapboxMap(null); iterator.remove(); } } @@ -409,20 +411,14 @@ public class MarkerViewManager { if (!markerViewMap.containsKey(marker)) { for (final MapboxMap.MarkerViewAdapter adapter : markerViewAdapters) { if (adapter.getMarkerClass().equals(marker.getClass())) { + + // Inflate View convertView = (View) adapter.getViewReusePool().acquire(); final View adaptedView = adapter.getView(marker, convertView, mapView); if (adaptedView != null) { - - // tilt adaptedView.setRotationX(marker.getTilt()); - - // rotation adaptedView.setRotation(marker.getRotation()); - - // alpha adaptedView.setAlpha(marker.getAlpha()); - - // visible adaptedView.setVisibility(View.GONE); if (mapboxMap.getSelectedMarkers().contains(marker)) { @@ -448,6 +444,7 @@ public class MarkerViewManager { } }); + marker.setMapboxMap(mapboxMap); markerViewMap.put(marker, adaptedView); if (convertView == null) { adaptedView.setVisibility(View.GONE); diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/annotation/MarkerViewActivity.java b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/annotation/MarkerViewActivity.java index 8d678794c..fe20b75a8 100644 --- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/annotation/MarkerViewActivity.java +++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/annotation/MarkerViewActivity.java @@ -146,7 +146,7 @@ public class MarkerViewActivity extends AppCompatActivity { public void onMapChanged(@MapView.MapChange int change) { if (change == MapView.REGION_IS_CHANGING || change == MapView.REGION_DID_CHANGE) { if (!markerViewManager.getMarkerViewAdapters().isEmpty() && viewCountView != null) { - viewCountView.setText("ViewCache size " + (mapView.getChildCount() - 5)); + viewCountView.setText("ViewCache size " + mapView.getMarkerViewContainer().getChildCount()); } } } @@ -194,6 +194,7 @@ public class MarkerViewActivity extends AppCompatActivity { protected void onStop() { super.onStop(); locationUpdateHandler.removeCallbacks(moveMarkerRunnable); + rotateUpdateHandler.removeCallbacks(rotateMarkerRunnable); } /**