summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPablo Guardiola <guardiola31337@gmail.com>2017-11-10 12:56:06 +0100
committerGitHub <noreply@github.com>2017-11-10 12:56:06 +0100
commitb5140cb3426595646f39aee298ca8306d3bd0a6f (patch)
tree2070ffb6e52b62860785a777227867c899697d85
parent91dabd01dfcd52dc40aa1c1d1db9d3f48f7abc97 (diff)
downloadqtlocation-mapboxgl-b5140cb3426595646f39aee298ca8306d3bd0a6f.tar.gz
[android] Cherry picks to agua (#10442)
* [android] fix map snapshotter marker example The reference to the MapSnapshotter needs to be held for the duration of the snapshot, otherwise it might be GC'd * [android] MapRendererRunnable - avoid weak reference table overflow Apparently on some devices the weak reference table is limited (numbers around 52000). Even though we don't use that many weak references, when GC is not called for a while they can stack up and a crash will occur before the GC has had the time to clear the references. The C++ peer now holds on to a global ref (strong) which can be obtained to queue the java peer and then release automatically so that the GC can take over after the runnable has been executed.
-rw-r--r--platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/snapshot/MapSnapshotterMarkerActivity.java4
-rw-r--r--platform/android/src/map_renderer.cpp10
-rw-r--r--platform/android/src/map_renderer_runnable.cpp10
-rw-r--r--platform/android/src/map_renderer_runnable.hpp7
4 files changed, 19 insertions, 12 deletions
diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/snapshot/MapSnapshotterMarkerActivity.java b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/snapshot/MapSnapshotterMarkerActivity.java
index 582d4a29c5..781e7b6334 100644
--- a/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/snapshot/MapSnapshotterMarkerActivity.java
+++ b/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/snapshot/MapSnapshotterMarkerActivity.java
@@ -25,6 +25,8 @@ import timber.log.Timber;
*/
public class MapSnapshotterMarkerActivity extends AppCompatActivity implements MapSnapshotter.SnapshotReadyCallback {
+ private MapSnapshotter mapSnapshotter;
+
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
@@ -40,7 +42,7 @@ public class MapSnapshotterMarkerActivity extends AppCompatActivity implements M
Timber.i("Starting snapshot");
- MapSnapshotter mapSnapshotter = new MapSnapshotter(
+ mapSnapshotter = new MapSnapshotter(
getApplicationContext(),
new MapSnapshotter
.Options(Math.min(container.getMeasuredWidth(), 1024), Math.min(container.getMeasuredHeight(), 1024))
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;
};