[android] shutting down thread pool of the CustomGeometrySource when the source is destroyed
This commit is contained in:
committed by
Łukasz Paczos
parent
b500577bfa
commit
63d4ac05f2
@@ -15,18 +15,26 @@ import java.lang.ref.WeakReference;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.ThreadFactory;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
import java.util.concurrent.locks.Lock;
|
||||
import java.util.concurrent.locks.ReentrantLock;
|
||||
|
||||
/**
|
||||
* Custom Vector Source, allows using FeatureCollections.
|
||||
*
|
||||
*/
|
||||
@UiThread
|
||||
public class CustomGeometrySource extends Source {
|
||||
public static final String THREAD_PREFIX = "CustomGeom";
|
||||
public static final int THREAD_POOL_LIMIT = 4;
|
||||
private static final AtomicInteger poolCount = new AtomicInteger();
|
||||
private final Lock executorLock = new ReentrantLock();
|
||||
private ExecutorService executor;
|
||||
private GeometryTileProvider provider;
|
||||
private final Map<TileID, AtomicBoolean> cancelledTileRequests = new ConcurrentHashMap<>();
|
||||
@@ -34,7 +42,7 @@ public class CustomGeometrySource extends Source {
|
||||
/**
|
||||
* Create a CustomGeometrySource
|
||||
*
|
||||
* @param id The source id.
|
||||
* @param id The source id.
|
||||
* @param provider The tile provider that returns geometry data for this source.
|
||||
*/
|
||||
public CustomGeometrySource(String id, GeometryTileProvider provider) {
|
||||
@@ -45,21 +53,20 @@ public class CustomGeometrySource extends Source {
|
||||
* Create a CustomGeometrySource with non-default CustomGeometrySourceOptions.
|
||||
* <p>Supported options are minZoom, maxZoom, buffer, and tolerance.</p>
|
||||
*
|
||||
* @param id The source id.
|
||||
* @param id The source id.
|
||||
* @param provider The tile provider that returns geometry data for this source.
|
||||
* @param options CustomGeometrySourceOptions.
|
||||
* @param options CustomGeometrySourceOptions.
|
||||
*/
|
||||
public CustomGeometrySource(String id, GeometryTileProvider provider, CustomGeometrySourceOptions options) {
|
||||
super();
|
||||
this.provider = provider;
|
||||
executor = Executors.newFixedThreadPool(4);
|
||||
initialize(id, options);
|
||||
}
|
||||
|
||||
/**
|
||||
* Invalidate previously provided features within a given bounds at all zoom levels.
|
||||
* Invoking this method will result in new requests to `GeometryTileProvider` for regions
|
||||
* that contain, include, or intersect with the provided bounds.
|
||||
* Invalidate previously provided features within a given bounds at all zoom levels.
|
||||
* Invoking this method will result in new requests to `GeometryTileProvider` for regions
|
||||
* that contain, include, or intersect with the provided bounds.
|
||||
*
|
||||
* @param bounds The region in which features should be invalidated at all zoom levels
|
||||
*/
|
||||
@@ -73,8 +80,8 @@ public class CustomGeometrySource extends Source {
|
||||
* in new requests to `GeometryTileProvider` for visible tiles.
|
||||
*
|
||||
* @param zoomLevel Tile zoom level.
|
||||
* @param x Tile X coordinate.
|
||||
* @param y Tile Y coordinate.
|
||||
* @param x Tile X coordinate.
|
||||
* @param y Tile Y coordinate.
|
||||
*/
|
||||
public void invalidateTile(int zoomLevel, int x, int y) {
|
||||
checkThread();
|
||||
@@ -87,9 +94,9 @@ public class CustomGeometrySource extends Source {
|
||||
* background threads.
|
||||
*
|
||||
* @param zoomLevel Tile zoom level.
|
||||
* @param x Tile X coordinate.
|
||||
* @param y Tile Y coordinate.
|
||||
* @param data Feature collection for the tile.
|
||||
* @param x Tile X coordinate.
|
||||
* @param y Tile Y coordinate.
|
||||
* @param data Feature collection for the tile.
|
||||
*/
|
||||
public void setTileData(int zoomLevel, int x, int y, FeatureCollection data) {
|
||||
checkThread();
|
||||
@@ -140,7 +147,15 @@ public class CustomGeometrySource extends Source {
|
||||
TileID tileID = new TileID(z, x, y);
|
||||
cancelledTileRequests.put(tileID, cancelFlag);
|
||||
GeometryTileRequest request = new GeometryTileRequest(tileID, provider, this, cancelFlag);
|
||||
executor.execute(request);
|
||||
|
||||
executorLock.lock();
|
||||
try {
|
||||
if (executor != null && !executor.isShutdown()) {
|
||||
executor.execute(request);
|
||||
}
|
||||
} finally {
|
||||
executorLock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
@WorkerThread
|
||||
@@ -152,6 +167,40 @@ public class CustomGeometrySource extends Source {
|
||||
}
|
||||
}
|
||||
|
||||
@Keep
|
||||
private void startThreads() {
|
||||
executorLock.lock();
|
||||
try {
|
||||
if (executor != null && !executor.isShutdown()) {
|
||||
executor.shutdownNow();
|
||||
}
|
||||
|
||||
executor = Executors.newFixedThreadPool(THREAD_POOL_LIMIT, new ThreadFactory() {
|
||||
final AtomicInteger threadCount = new AtomicInteger();
|
||||
final int poolId = poolCount.getAndIncrement();
|
||||
|
||||
@Override
|
||||
public Thread newThread(@NonNull Runnable runnable) {
|
||||
return new Thread(
|
||||
runnable,
|
||||
String.format(Locale.US, "%s-%d-%d", THREAD_PREFIX, poolId, threadCount.getAndIncrement()));
|
||||
}
|
||||
});
|
||||
} finally {
|
||||
executorLock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
@Keep
|
||||
private void releaseThreads() {
|
||||
executorLock.lock();
|
||||
try {
|
||||
executor.shutdownNow();
|
||||
} finally {
|
||||
executorLock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
private static class TileID {
|
||||
public int z;
|
||||
public int x;
|
||||
@@ -164,7 +213,7 @@ public class CustomGeometrySource extends Source {
|
||||
}
|
||||
|
||||
public int hashCode() {
|
||||
return Arrays.hashCode(new int[]{z, x, y});
|
||||
return Arrays.hashCode(new int[] {z, x, y});
|
||||
}
|
||||
|
||||
public boolean equals(Object object) {
|
||||
@@ -177,7 +226,7 @@ public class CustomGeometrySource extends Source {
|
||||
}
|
||||
|
||||
if (object instanceof TileID) {
|
||||
TileID other = (TileID)object;
|
||||
TileID other = (TileID) object;
|
||||
return this.z == other.z && this.x == other.x && this.y == other.y;
|
||||
}
|
||||
return false;
|
||||
@@ -205,7 +254,7 @@ public class CustomGeometrySource extends Source {
|
||||
|
||||
FeatureCollection data = provider.getFeaturesForBounds(LatLngBounds.from(id.z, id.x, id.y), id.z);
|
||||
CustomGeometrySource source = sourceRef.get();
|
||||
if (!isCancelled() && source != null && data != null) {
|
||||
if (!isCancelled() && source != null && data != null) {
|
||||
source.setTileData(id, data);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user