diff options
author | Łukasz Paczos <lukas.paczos@gmail.com> | 2018-07-31 19:42:09 +0200 |
---|---|---|
committer | Łukasz Paczos <lukasz.paczos@mapbox.com> | 2018-08-10 18:31:52 +0200 |
commit | 63d4ac05f20190d7ac3df1f852840e9678b9e7dd (patch) | |
tree | 563c6308ca6c0c8cad0e4a10a1c76352c2e31cc8 /platform/android/src | |
parent | b500577bfa9759241b374c161a06c1bef79cf4cd (diff) | |
download | qtlocation-mapboxgl-63d4ac05f20190d7ac3df1f852840e9678b9e7dd.tar.gz |
[android] shutting down thread pool of the CustomGeometrySource when the source is destroyed
Diffstat (limited to 'platform/android/src')
5 files changed, 56 insertions, 5 deletions
diff --git a/platform/android/src/native_map_view.cpp b/platform/android/src/native_map_view.cpp index 44b04fc538..8da44c10cb 100755 --- a/platform/android/src/native_map_view.cpp +++ b/platform/android/src/native_map_view.cpp @@ -892,7 +892,9 @@ void NativeMapView::removeSource(JNIEnv& env, jni::Object<Source> obj, jlong sou assert(sourcePtr != 0); mbgl::android::Source *source = reinterpret_cast<mbgl::android::Source *>(sourcePtr); - source->removeFromMap(env, obj, *map); + if (source->removeFromMap(env, obj, *map)) { + source->releaseJavaPeer(); + } } void NativeMapView::addImage(JNIEnv& env, jni::String name, jni::Object<Bitmap> bitmap, jni::jfloat scale, jni::jboolean sdf) { diff --git a/platform/android/src/style/sources/custom_geometry_source.cpp b/platform/android/src/style/sources/custom_geometry_source.cpp index b38405a3b1..9c51f70ab5 100644 --- a/platform/android/src/style/sources/custom_geometry_source.cpp +++ b/platform/android/src/style/sources/custom_geometry_source.cpp @@ -54,7 +54,9 @@ namespace android { : Source(env, coreSource, createJavaPeer(env), frontend) { } - CustomGeometrySource::~CustomGeometrySource() = default; + CustomGeometrySource::~CustomGeometrySource() { + releaseThreads(); + } void CustomGeometrySource::fetchTile (const mbgl::CanonicalTileID& tileID) { android::UniqueEnv _env = android::AttachEnv(); @@ -78,6 +80,28 @@ namespace android { peer.Call(*_env, cancelTile, (int)tileID.z, (int)tileID.x, (int)tileID.y); }; + void CustomGeometrySource::startThreads() { + android::UniqueEnv _env = android::AttachEnv(); + + static auto startThreads = javaClass.GetMethod<void ()>(*_env, "startThreads"); + + assert(javaPeer); + + auto peer = jni::Cast(*_env, *javaPeer, javaClass); + peer.Call(*_env, startThreads); + } + + void CustomGeometrySource::releaseThreads() { + android::UniqueEnv _env = android::AttachEnv(); + + static auto releaseThreads = javaClass.GetMethod<void ()>(*_env, "releaseThreads"); + + assert(javaPeer); + + auto peer = jni::Cast(*_env, *javaPeer, javaClass); + peer.Call(*_env, releaseThreads); + }; + void CustomGeometrySource::setTileData(jni::JNIEnv& env, jni::jint z, jni::jint x, @@ -120,6 +144,19 @@ namespace android { return jni::Object<Source>(CustomGeometrySource::javaClass.New(env, constructor, reinterpret_cast<jni::jlong>(this)).Get()); } + void CustomGeometrySource::addToMap(JNIEnv& env, jni::Object<Source> obj, mbgl::Map& map, AndroidRendererFrontend& frontend) { + Source::addToMap(env, obj, map, frontend); + startThreads(); + } + + bool CustomGeometrySource::removeFromMap(JNIEnv& env, jni::Object<Source> source, mbgl::Map& map) { + bool successfullyRemoved = Source::removeFromMap(env, source, map); + if (successfullyRemoved) { + releaseThreads(); + } + return successfullyRemoved; + } + void CustomGeometrySource::registerNative(jni::JNIEnv& env) { // Lookup the class CustomGeometrySource::javaClass = *jni::Class<CustomGeometrySource>::Find(env).NewGlobalRef(env).release(); diff --git a/platform/android/src/style/sources/custom_geometry_source.hpp b/platform/android/src/style/sources/custom_geometry_source.hpp index 1dc1c07b4f..c38926a5b9 100644 --- a/platform/android/src/style/sources/custom_geometry_source.hpp +++ b/platform/android/src/style/sources/custom_geometry_source.hpp @@ -28,8 +28,13 @@ public: ~CustomGeometrySource(); + bool removeFromMap(JNIEnv&, jni::Object<Source>, mbgl::Map&) override; + void addToMap(JNIEnv&, jni::Object<Source>, mbgl::Map&, AndroidRendererFrontend&) override; + void fetchTile(const mbgl::CanonicalTileID& tileID); void cancelTile(const mbgl::CanonicalTileID& tileID); + void startThreads(); + void releaseThreads(); void setTileData(jni::JNIEnv& env, jni::jint z, jni::jint x, jni::jint y, jni::Object<geojson::FeatureCollection> jf); void invalidateTile(jni::JNIEnv& env, jni::jint z, jni::jint x, jni::jint y); diff --git a/platform/android/src/style/sources/source.cpp b/platform/android/src/style/sources/source.cpp index 5f68e40467..8f14ebc43e 100644 --- a/platform/android/src/style/sources/source.cpp +++ b/platform/android/src/style/sources/source.cpp @@ -109,7 +109,7 @@ namespace android { rendererFrontend = &frontend; } - void Source::removeFromMap(JNIEnv&, jni::Object<Source>, mbgl::Map& map) { + bool Source::removeFromMap(JNIEnv&, jni::Object<Source>, mbgl::Map& map) { // Cannot remove if not attached yet if (ownedSource) { throw std::runtime_error("Cannot remove detached source"); @@ -119,6 +119,11 @@ namespace android { ownedSource = map.getStyle().removeSource(source.getID()); // The source may not be removed if any layers still reference it + return ownedSource != nullptr; + } + + void Source::releaseJavaPeer() { + // We can't release the peer if the source was not removed from the map if (!ownedSource) { return; } diff --git a/platform/android/src/style/sources/source.hpp b/platform/android/src/style/sources/source.hpp index 718f60b381..6b906eb9c0 100644 --- a/platform/android/src/style/sources/source.hpp +++ b/platform/android/src/style/sources/source.hpp @@ -35,9 +35,11 @@ public: virtual ~Source(); - void addToMap(JNIEnv&, jni::Object<Source>, mbgl::Map&, AndroidRendererFrontend&); + virtual void addToMap(JNIEnv&, jni::Object<Source>, mbgl::Map&, AndroidRendererFrontend&); - void removeFromMap(JNIEnv&, jni::Object<Source>, mbgl::Map&); + virtual bool removeFromMap(JNIEnv&, jni::Object<Source>, mbgl::Map&); + + void releaseJavaPeer(); jni::String getId(jni::JNIEnv&); |