[android] #3276 - using a pool to do view reuse
This commit is contained in:
@@ -94,9 +94,11 @@ import java.lang.annotation.RetentionPolicy;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Hashtable;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.CopyOnWriteArrayList;
|
||||
|
||||
/**
|
||||
@@ -155,8 +157,9 @@ public class MapView extends FrameLayout {
|
||||
private StyleInitializer mStyleInitializer;
|
||||
|
||||
private List<OnMapReadyCallback> mOnMapReadyCallbackList;
|
||||
private long nViewMarkerBoundsUpdateTime;
|
||||
|
||||
private long mViewMarkerBoundsUpdateTime;
|
||||
private boolean mViewMarkersUpdateRunning;
|
||||
|
||||
@UiThread
|
||||
public MapView(@NonNull Context context) {
|
||||
super(context);
|
||||
@@ -455,12 +458,11 @@ public class MapView extends FrameLayout {
|
||||
|
||||
long currentTime = SystemClock.elapsedRealtime();
|
||||
|
||||
if (currentTime < nViewMarkerBoundsUpdateTime) {
|
||||
if (mViewMarkersUpdateRunning || currentTime < mViewMarkerBoundsUpdateTime) {
|
||||
return;
|
||||
}
|
||||
|
||||
nViewMarkerBoundsUpdateTime = currentTime + 300;
|
||||
|
||||
|
||||
mViewMarkerBoundsUpdateTime = currentTime + 300;
|
||||
new MarkerInBoundsTask().execute();
|
||||
}
|
||||
}
|
||||
@@ -475,14 +477,24 @@ public class MapView extends FrameLayout {
|
||||
}
|
||||
}
|
||||
|
||||
private class MarkerInBoundsTask extends AsyncTask<Void, Void, Void>{
|
||||
|
||||
public class MarkerInBoundsTask extends AsyncTask<Void, Void, MarkerInBoundsTask.Result> {
|
||||
|
||||
@Override
|
||||
protected Void doInBackground(Void... params) {
|
||||
protected void onPreExecute() {
|
||||
super.onPreExecute();
|
||||
mViewMarkersUpdateRunning = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Result doInBackground(Void... params) {
|
||||
List<Marker> inBounds = new ArrayList<>();
|
||||
Map<Marker, View> outBounds = new HashMap<>();
|
||||
|
||||
LatLngBounds bounds = mMapboxMap.getProjection().getVisibleRegion().latLngBounds;
|
||||
long[] ids = mNativeMapView.getAnnotationsInBounds(bounds);
|
||||
LongSparseArray<View> markerViews = mMapboxMap.getMarkerViews();
|
||||
|
||||
MapboxMap.MarkerViewAdapter adapter = mMapboxMap.getMarkerViewAdapter();
|
||||
Log.v(MapboxConstants.TAG, "Annotations in bounds: " + ids.length);
|
||||
|
||||
boolean found;
|
||||
long key;
|
||||
@@ -499,11 +511,12 @@ public class MapView extends FrameLayout {
|
||||
}
|
||||
|
||||
if (!found) {
|
||||
Log.v(MapboxConstants.TAG, "Adding " + id);
|
||||
// if(adapter!=null) {
|
||||
// mMapboxMap.addMarkerView(id, adapter.getView((Marker) mMapboxMap.getAnnotation(id), null, MapView.this));
|
||||
// }
|
||||
markerViews.append(id, null);
|
||||
Annotation annotation = mMapboxMap.getAnnotation(id);
|
||||
if (annotation instanceof Marker) {
|
||||
inBounds.add((Marker) annotation);
|
||||
} else {
|
||||
Log.v(MapboxConstants.TAG, "Not instance of Marker" + id);
|
||||
}
|
||||
} else {
|
||||
Log.v(MapboxConstants.TAG, "Already added " + id);
|
||||
}
|
||||
@@ -519,13 +532,42 @@ public class MapView extends FrameLayout {
|
||||
}
|
||||
}
|
||||
if (!found) {
|
||||
Log.v(MapboxConstants.TAG, "Removing " + key);
|
||||
markerViews.remove(key);
|
||||
Annotation annotation = mMapboxMap.getAnnotation(key);
|
||||
if (annotation instanceof Marker) {
|
||||
outBounds.put((Marker) annotation, markerViews.get(key));
|
||||
} else {
|
||||
Log.v(MapboxConstants.TAG, "Not instance of Marker" + key);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Log.v(MapboxConstants.TAG, "Amount of annotations: " + markerViews.size());
|
||||
return null;
|
||||
return new Result(inBounds, outBounds);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPostExecute(Result result) {
|
||||
super.onPostExecute(result);
|
||||
mMapboxMap.setViewMarkersBoundsTaskResult(result);
|
||||
mViewMarkersUpdateRunning = false;
|
||||
Log.v(MapboxConstants.TAG, "Amount of child views " + getChildCount());
|
||||
}
|
||||
|
||||
public class Result {
|
||||
private List<Marker> inBounds;
|
||||
private Map<Marker, View> outBounds;
|
||||
|
||||
public Result(List<Marker> inBounds, Map<Marker, View> outBounds) {
|
||||
this.inBounds = inBounds;
|
||||
this.outBounds = outBounds;
|
||||
}
|
||||
|
||||
public List<Marker> getInBounds() {
|
||||
return inBounds;
|
||||
}
|
||||
|
||||
public Map<Marker, View> getOutBounds() {
|
||||
return outBounds;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -3,12 +3,15 @@ package com.mapbox.mapboxsdk.maps;
|
||||
import android.content.Context;
|
||||
import android.graphics.Bitmap;
|
||||
import android.location.Location;
|
||||
import android.os.Handler;
|
||||
import android.os.Looper;
|
||||
import android.os.SystemClock;
|
||||
import android.support.annotation.FloatRange;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.annotation.UiThread;
|
||||
import android.support.v4.util.LongSparseArray;
|
||||
import android.support.v4.util.Pools;
|
||||
import android.text.TextUtils;
|
||||
import android.util.Log;
|
||||
import android.view.View;
|
||||
@@ -41,6 +44,7 @@ import com.mapbox.mapboxsdk.maps.widgets.MyLocationViewSettings;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
/**
|
||||
@@ -89,6 +93,8 @@ public class MapboxMap {
|
||||
private double mMaxZoomLevel = -1;
|
||||
private double mMinZoomLevel = -1;
|
||||
|
||||
private Pools.SimplePool<View> viewSimplePool = new Pools.SimplePool<>(20);
|
||||
|
||||
MapboxMap(@NonNull MapView mapView) {
|
||||
mMapView = mapView;
|
||||
mMapView.addOnMapChangedListener(new MapChangeCameraPositionListener());
|
||||
@@ -631,9 +637,29 @@ public class MapboxMap {
|
||||
// Annotations
|
||||
//
|
||||
|
||||
public void addMarkerView(long key, View markerView) {
|
||||
mMarkerViews.append(key, markerView);
|
||||
mMapView.addView(markerView);
|
||||
void setViewMarkersBoundsTaskResult(MapView.MarkerInBoundsTask.Result result) {
|
||||
Map<Marker, View> outBoundsMarker = result.getOutBounds();
|
||||
View convertView;
|
||||
for (Map.Entry<Marker, View> outBoundsEntry : outBoundsMarker.entrySet()) {
|
||||
convertView = outBoundsEntry.getValue();
|
||||
if (convertView != null) {
|
||||
convertView.setVisibility(View.GONE);
|
||||
viewSimplePool.release(convertView);
|
||||
mMarkerViews.remove(outBoundsEntry.getKey().getId());
|
||||
}
|
||||
}
|
||||
|
||||
List<Marker> inBoundsMarkers = result.getInBounds();
|
||||
for (Marker marker : inBoundsMarkers) {
|
||||
convertView = viewSimplePool.acquire();
|
||||
View adaptedView = mMarkerViewAdapter.getView(marker, convertView, mMapView);
|
||||
mMarkerViews.append(marker.getId(), adaptedView);
|
||||
if (convertView == null) {
|
||||
mMapView.addView(adaptedView);
|
||||
} else {
|
||||
convertView.setVisibility(View.VISIBLE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -984,7 +1010,6 @@ public class MapboxMap {
|
||||
*
|
||||
* @return An annotation with a matched id, null is returned if no match was found.
|
||||
*/
|
||||
@UiThread
|
||||
@Nullable
|
||||
public Annotation getAnnotation(long id) {
|
||||
return mAnnotations.get(id);
|
||||
|
||||
Reference in New Issue
Block a user