[android] #3276 - using a pool to do view reuse

This commit is contained in:
Tobrun
2016-05-04 12:27:48 +02:00
parent c53533270b
commit b7d47d4c3f
3 changed files with 94 additions and 27 deletions

View File

@@ -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;
}
}
}

View File

@@ -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);