diff options
-rw-r--r-- | platform/android/src/map_renderer.cpp | 10 | ||||
-rw-r--r-- | platform/android/src/map_renderer_runnable.cpp | 10 | ||||
-rw-r--r-- | platform/android/src/map_renderer_runnable.hpp | 7 |
3 files changed, 16 insertions, 11 deletions
diff --git a/platform/android/src/map_renderer.cpp b/platform/android/src/map_renderer.cpp index 7655455210..36e8142bfa 100644 --- a/platform/android/src/map_renderer.cpp +++ b/platform/android/src/map_renderer.cpp @@ -41,15 +41,19 @@ ActorRef<Renderer> MapRenderer::actor() const { } void MapRenderer::schedule(std::weak_ptr<Mailbox> scheduled) { - // Create a runnable and schedule it on the gl thread + // Create a runnable android::UniqueEnv _env = android::AttachEnv(); auto runnable = std::make_unique<MapRendererRunnable>(*_env, std::move(scheduled)); + // Obtain ownership of the peer (gets transferred to the MapRenderer on the JVM for later GC) + auto peer = runnable->peer(); + + // Queue the event on the Java Peer static auto queueEvent = javaClass.GetMethod<void( jni::Object<MapRendererRunnable>)>(*_env, "queueEvent"); - javaPeer->Call(*_env, queueEvent, runnable->getPeer()); + javaPeer->Call(*_env, queueEvent, *peer); - // Release the object as it will be destroyed on GC of the Java Peer + // Release the c++ peer as it will be destroyed on GC of the Java Peer runnable.release(); } diff --git a/platform/android/src/map_renderer_runnable.cpp b/platform/android/src/map_renderer_runnable.cpp index df8cba5e55..4dc6611c40 100644 --- a/platform/android/src/map_renderer_runnable.cpp +++ b/platform/android/src/map_renderer_runnable.cpp @@ -8,11 +8,13 @@ namespace android { MapRendererRunnable::MapRendererRunnable(jni::JNIEnv& env, std::weak_ptr<Mailbox> mailbox_) : mailbox(std::move(mailbox_)) { - // Create the Java peer + // Create the Java peer and hold on to a global reference + // Not using a weak reference here as this might oerflow + // the weak reference table on some devices jni::UniqueLocalFrame frame = jni::PushLocalFrame(env, 5); static auto constructor = javaClass.GetConstructor<jlong>(env); auto instance = javaClass.New(env, constructor, reinterpret_cast<jlong>(this)); - javaPeer = SeizeGenericWeakRef(env, jni::Object<MapRendererRunnable>(jni::NewWeakGlobalRef(env, instance.Get()).release())); + javaPeer = instance.NewGlobalRef(env); } MapRendererRunnable::~MapRendererRunnable() = default; @@ -21,8 +23,8 @@ void MapRendererRunnable::run(jni::JNIEnv&) { Mailbox::maybeReceive(mailbox); } -jni::Object<MapRendererRunnable> MapRendererRunnable::getPeer() { - return *javaPeer; +jni::UniqueObject<MapRendererRunnable> MapRendererRunnable::peer() { + return std::move(javaPeer); } // Static methods // diff --git a/platform/android/src/map_renderer_runnable.hpp b/platform/android/src/map_renderer_runnable.hpp index 75646a442d..46fb028d26 100644 --- a/platform/android/src/map_renderer_runnable.hpp +++ b/platform/android/src/map_renderer_runnable.hpp @@ -8,8 +8,6 @@ #include <jni/jni.hpp> -#include "jni/generic_global_ref_deleter.hpp" - namespace mbgl { namespace android { @@ -39,10 +37,11 @@ public: void run(jni::JNIEnv&); - jni::Object<MapRendererRunnable> getPeer(); + // Transfers ownership of the Peer object to the caller + jni::UniqueObject<MapRendererRunnable> peer(); private: - GenericUniqueWeakObject<MapRendererRunnable> javaPeer; + jni::UniqueObject<MapRendererRunnable> javaPeer; std::weak_ptr<Mailbox> mailbox; }; |