diff --git a/platform/android/MapLibreAndroid/src/cpp/android_renderer_frontend.cpp b/platform/android/MapLibreAndroid/src/cpp/android_renderer_frontend.cpp index 6ecc42981..764fac17d 100644 --- a/platform/android/MapLibreAndroid/src/cpp/android_renderer_frontend.cpp +++ b/platform/android/MapLibreAndroid/src/cpp/android_renderer_frontend.cpp @@ -9,8 +9,10 @@ #include #include #include +#include #include "android_renderer_backend.hpp" +#include "attach_env.hpp" namespace mbgl { namespace android { @@ -91,23 +93,38 @@ private: ActorRef delegate; }; -AndroidRendererFrontend::AndroidRendererFrontend(Private, MapRenderer& mapRenderer_) - : mapRenderer(mapRenderer_), +AndroidRendererFrontend::AndroidRendererFrontend(Private, + jni::JNIEnv& env, + const jni::Object& mapRendererObj) + : mapRenderer(MapRenderer::getNativePeer(env, mapRendererObj)), mapRunLoop(util::RunLoop::Get()) {} -std::shared_ptr AndroidRendererFrontend::create(MapRenderer& mapRenderer) { - auto ptr = std::make_shared(Private(), mapRenderer); - ptr->init(); +std::shared_ptr AndroidRendererFrontend::create( + jni::JNIEnv& env, const jni::Object& mapRendererObj) { + auto ptr = std::make_shared(Private(), env, mapRendererObj); + ptr->init(env, mapRendererObj); return ptr; } -void AndroidRendererFrontend::init() { - updateAsyncTask = std::make_unique([weakSelf = weak_from_this()]() { - if (auto self = weakSelf.lock()) { - self->mapRenderer.update(std::move(self->updateParams)); - self->mapRenderer.requestRender(); - } - }); +void AndroidRendererFrontend::init(jni::JNIEnv& env, const jni::Object& mapRendererObj) { + auto weakMapRenderer = std::make_shared>>(env, mapRendererObj); + + updateAsyncTask = std::make_unique( + [weakSelf = weak_from_this(), weakMapRenderer = std::move(weakMapRenderer)]() { + if (auto self = weakSelf.lock()) { + try { + android::UniqueEnv _env = android::AttachEnv(); + auto mapRendererRef = weakMapRenderer->get(*_env); + if (mapRendererRef) { + self->mapRenderer.update(std::move(self->updateParams)); + self->mapRenderer.requestRender(*_env, mapRendererRef); + } + } catch (const std::exception& exception) { + Log::Error(Event::Android, + std::string("AndroidRendererFrontend::updateAsyncTask failed: ") + exception.what()); + } + } + }); } AndroidRendererFrontend::~AndroidRendererFrontend() = default; diff --git a/platform/android/MapLibreAndroid/src/cpp/android_renderer_frontend.hpp b/platform/android/MapLibreAndroid/src/cpp/android_renderer_frontend.hpp index 3210634fa..60c273815 100644 --- a/platform/android/MapLibreAndroid/src/cpp/android_renderer_frontend.hpp +++ b/platform/android/MapLibreAndroid/src/cpp/android_renderer_frontend.hpp @@ -14,6 +14,8 @@ #include "map_renderer.hpp" +#include + namespace mbgl { class RenderedQueryOptions; @@ -33,10 +35,9 @@ class AndroidRendererFrontend : public RendererFrontend, public std::enable_shar }; public: - AndroidRendererFrontend(Private, MapRenderer&); - - static std::shared_ptr create(MapRenderer&); - void init(); + AndroidRendererFrontend(Private, jni::JNIEnv&, const jni::Object&); + static std::shared_ptr create(jni::JNIEnv&, const jni::Object&); + void init(jni::JNIEnv&, const jni::Object&); ~AndroidRendererFrontend() override; diff --git a/platform/android/MapLibreAndroid/src/cpp/map_renderer.cpp b/platform/android/MapLibreAndroid/src/cpp/map_renderer.cpp index fd75d2828..e17874ba1 100644 --- a/platform/android/MapLibreAndroid/src/cpp/map_renderer.cpp +++ b/platform/android/MapLibreAndroid/src/cpp/map_renderer.cpp @@ -138,6 +138,18 @@ void MapRenderer::requestRender() { } } +void MapRenderer::requestRender(JNIEnv& env, jni::Local>& ref) { + try { + static auto& javaClass = jni::Class::Singleton(env); + static auto onInvalidate = javaClass.GetMethod(env, "requestRender"); + if (ref) { + ref.Call(env, onInvalidate); + } + } catch (const std::exception& exception) { + Log::Error(Event::Android, std::string("MapRenderer::requestRender failed: ") + exception.what()); + } +} + void MapRenderer::update(std::shared_ptr params) { try { // Lock on the parameters diff --git a/platform/android/MapLibreAndroid/src/cpp/map_renderer.hpp b/platform/android/MapLibreAndroid/src/cpp/map_renderer.hpp index 9fc962c0d..84ed971c4 100644 --- a/platform/android/MapLibreAndroid/src/cpp/map_renderer.hpp +++ b/platform/android/MapLibreAndroid/src/cpp/map_renderer.hpp @@ -81,6 +81,7 @@ public: void waitForEmpty(const util::SimpleIdentity tag) override; void requestRender(); + void requestRender(JNIEnv&, jni::Local>&); // Snapshot - requires a RunLoop on the calling thread using SnapshotCallback = std::function; diff --git a/platform/android/MapLibreAndroid/src/cpp/native_map_view.cpp b/platform/android/MapLibreAndroid/src/cpp/native_map_view.cpp index c62cad5ff..e7a48ac3c 100644 --- a/platform/android/MapLibreAndroid/src/cpp/native_map_view.cpp +++ b/platform/android/MapLibreAndroid/src/cpp/native_map_view.cpp @@ -75,7 +75,7 @@ NativeMapView::NativeMapView(jni::JNIEnv& _env, } // Create a renderer frontend - rendererFrontend = AndroidRendererFrontend::create(mapRenderer); + rendererFrontend = AndroidRendererFrontend::create(_env, jMapRenderer); // Create Map options MapOptions options;