summaryrefslogtreecommitdiff
path: root/platform/android/src/file_source.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'platform/android/src/file_source.cpp')
-rw-r--r--platform/android/src/file_source.cpp58
1 files changed, 29 insertions, 29 deletions
diff --git a/platform/android/src/file_source.cpp b/platform/android/src/file_source.cpp
index 2a6cac3b02..d9b8e12dc4 100644
--- a/platform/android/src/file_source.cpp
+++ b/platform/android/src/file_source.cpp
@@ -1,4 +1,5 @@
#include "file_source.hpp"
+#include "attach_env.hpp"
#include <mbgl/actor/actor.hpp>
#include <mbgl/actor/scheduler.hpp>
@@ -6,7 +7,6 @@
#include <mbgl/util/logging.hpp>
#include "asset_manager_file_source.hpp"
-#include "jni/generic_global_ref_deleter.hpp"
namespace mbgl {
namespace android {
@@ -14,9 +14,9 @@ namespace android {
// FileSource //
FileSource::FileSource(jni::JNIEnv& _env,
- jni::String accessToken,
- jni::String _cachePath,
- jni::Object<AssetManager> assetManager) {
+ const jni::String& accessToken,
+ const jni::String& _cachePath,
+ const jni::Object<AssetManager>& assetManager) {
// Create a core default file source
fileSource = std::make_unique<mbgl::DefaultFileSource>(
jni::Make<std::string>(_env, _cachePath) + "/mbgl-offline.db",
@@ -31,30 +31,31 @@ FileSource::FileSource(jni::JNIEnv& _env,
FileSource::~FileSource() {
}
-jni::String FileSource::getAccessToken(jni::JNIEnv& env) {
+jni::Local<jni::String> FileSource::getAccessToken(jni::JNIEnv& env) {
return jni::Make<jni::String>(env, fileSource->getAccessToken());
}
-void FileSource::setAccessToken(jni::JNIEnv& env, jni::String token) {
+void FileSource::setAccessToken(jni::JNIEnv& env, const jni::String& token) {
fileSource->setAccessToken(jni::Make<std::string>(env, token));
}
-void FileSource::setAPIBaseUrl(jni::JNIEnv& env, jni::String url) {
+void FileSource::setAPIBaseUrl(jni::JNIEnv& env, const jni::String& url) {
fileSource->setAPIBaseURL(jni::Make<std::string>(env, url));
}
-void FileSource::setResourceTransform(jni::JNIEnv& env, jni::Object<FileSource::ResourceTransformCallback> transformCallback) {
+void FileSource::setResourceTransform(jni::JNIEnv& env, const jni::Object<FileSource::ResourceTransformCallback>& transformCallback) {
if (transformCallback) {
+ auto global = jni::NewGlobal<jni::EnvAttachingDeleter>(env, transformCallback);
resourceTransform = std::make_unique<Actor<ResourceTransform>>(*Scheduler::GetCurrent(),
// Capture the ResourceTransformCallback object as a managed global into
// the lambda. It is released automatically when we're setting a new ResourceTransform in
// a subsequent call.
// Note: we're converting it to shared_ptr because this lambda is converted to a std::function,
// which requires copyability of its captured variables.
- [callback = std::shared_ptr<jni::jobject>(transformCallback.NewGlobalRef(env).release()->Get(), GenericGlobalRefDeleter())]
+ [callback = std::make_shared<decltype(global)>(std::move(global))]
(mbgl::Resource::Kind kind, const std::string&& url_) {
android::UniqueEnv _env = android::AttachEnv();
- return FileSource::ResourceTransformCallback::onURL(*_env, jni::Object<FileSource::ResourceTransformCallback>(*callback), int(kind), url_);
+ return FileSource::ResourceTransformCallback::onURL(*_env, *callback, int(kind), url_);
});
fileSource->setResourceTransform(resourceTransform->self());
} else {
@@ -92,30 +93,32 @@ jni::jboolean FileSource::isResumed(jni::JNIEnv&) {
return (jboolean) false;
}
-jni::Class<FileSource> FileSource::javaClass;
-
-FileSource* FileSource::getNativePeer(jni::JNIEnv& env, jni::Object<FileSource> jFileSource) {
- static auto field = FileSource::javaClass.GetField<jlong>(env, "nativePtr");
+FileSource* FileSource::getNativePeer(jni::JNIEnv& env, const jni::Object<FileSource>& jFileSource) {
+ static auto& javaClass = jni::Class<FileSource>::Singleton(env);
+ static auto field = javaClass.GetField<jlong>(env, "nativePtr");
return reinterpret_cast<FileSource *>(jFileSource.Get(env, field));
}
-mbgl::DefaultFileSource& FileSource::getDefaultFileSource(jni::JNIEnv& env, jni::Object<FileSource> jFileSource) {
+mbgl::DefaultFileSource& FileSource::getDefaultFileSource(jni::JNIEnv& env, const jni::Object<FileSource>& jFileSource) {
FileSource* fileSource = FileSource::getNativePeer(env, jFileSource);
assert(fileSource != nullptr);
return *fileSource->fileSource;
}
void FileSource::registerNative(jni::JNIEnv& env) {
- //Register classes
- FileSource::javaClass = *jni::Class<FileSource>::Find(env).NewGlobalRef(env).release();
- FileSource::ResourceTransformCallback::javaClass = *jni::Class<FileSource::ResourceTransformCallback>::Find(env).NewGlobalRef(env).release();
+ // Ensure the class for ResourceTransformCallback is cached. If it's requested for the
+ // first time on a background thread, Android's class loader heuristics will fail.
+ // https://developer.android.com/training/articles/perf-jni#faq_FindClass
+ jni::Class<ResourceTransformCallback>::Singleton(env);
+
+ static auto& javaClass = jni::Class<FileSource>::Singleton(env);
#define METHOD(MethodPtr, name) jni::MakeNativePeerMethod<decltype(MethodPtr), (MethodPtr)>(name)
// Register the peer
jni::RegisterNativePeer<FileSource>(
- env, FileSource::javaClass, "nativePtr",
- std::make_unique<FileSource, JNIEnv&, jni::String, jni::String, jni::Object<AssetManager>>,
+ env, javaClass, "nativePtr",
+ jni::MakePeer<FileSource, const jni::String&, const jni::String&, const jni::Object<AssetManager>&>,
"initialize",
"finalize",
METHOD(&FileSource::getAccessToken, "getAccessToken"),
@@ -131,16 +134,13 @@ void FileSource::registerNative(jni::JNIEnv& env) {
// FileSource::ResourceTransformCallback //
-jni::Class<FileSource::ResourceTransformCallback> FileSource::ResourceTransformCallback::javaClass;
-
-std::string FileSource::ResourceTransformCallback::onURL(jni::JNIEnv& env, jni::Object<FileSource::ResourceTransformCallback> callback, int kind, std::string url_) {
- static auto method = FileSource::ResourceTransformCallback::javaClass.GetMethod<jni::String (jni::jint, jni::String)>(env, "onURL");
- auto url = jni::Make<jni::String>(env, url_);
+std::string FileSource::ResourceTransformCallback::onURL(jni::JNIEnv& env, const jni::Object<FileSource::ResourceTransformCallback>& callback, int kind, std::string url_) {
+ static auto& javaClass = jni::Class<FileSource::ResourceTransformCallback>::Singleton(env);
+ static auto method = javaClass.GetMethod<jni::String (jni::jint, jni::String)>(env, "onURL");
- url = callback.Call(env, method, kind, url);
- auto urlStr = jni::Make<std::string>(env, url);
- jni::DeleteLocalRef(env, url);
- return urlStr;
+ return jni::Make<std::string>(env,
+ callback.Call(env, method, kind,
+ jni::Make<jni::String>(env, url_)));
}
} // namespace android