[android] Reuse Java Source objects by holding on to a strong reference in the C++ peer.

This commit is contained in:
Asheem Mamoowala
2017-11-13 16:06:26 -08:00
parent 3067b77c65
commit f06ebcc967
21 changed files with 187 additions and 197 deletions

View File

@@ -733,7 +733,7 @@ final class NativeMapView {
if (isDestroyedOn("addSource")) {
return;
}
nativeAddSource(source.getNativePtr());
nativeAddSource(source, source.getNativePtr());
}
@Nullable
@@ -741,14 +741,15 @@ final class NativeMapView {
if (isDestroyedOn("removeSource")) {
return null;
}
return nativeRemoveSourceById(sourceId);
Source source = getSource(sourceId);
return removeSource(source);
}
public Source removeSource(@NonNull Source source) {
if (isDestroyedOn("removeSource")) {
return null;
}
nativeRemoveSource(source.getNativePtr());
nativeRemoveSource(source, source.getNativePtr());
return source;
}
@@ -1027,11 +1028,9 @@ final class NativeMapView {
private native Source nativeGetSource(String sourceId);
private native void nativeAddSource(long nativeSourcePtr) throws CannotAddSourceException;
private native void nativeAddSource(Source source, long sourcePtr) throws CannotAddSourceException;
private native Source nativeRemoveSourceById(String sourceId);
private native void nativeRemoveSource(long sourcePtr);
private native void nativeRemoveSource(Source source, long sourcePtr);
private native void nativeAddImage(String name, int width, int height, float pixelRatio,
byte[] array);

View File

@@ -181,8 +181,6 @@ add_library(mbgl-android STATIC
platform/android/src/style/sources/custom_geometry_source.hpp
platform/android/src/style/sources/source.cpp
platform/android/src/style/sources/source.hpp
platform/android/src/style/sources/sources.cpp
platform/android/src/style/sources/sources.hpp
platform/android/src/style/sources/raster_source.cpp
platform/android/src/style/sources/raster_source.hpp
platform/android/src/style/sources/unknown_source.cpp

View File

@@ -47,7 +47,7 @@
#include "style/functions/interval_stops.hpp"
#include "style/functions/stop.hpp"
#include "style/layers/layers.hpp"
#include "style/sources/sources.hpp"
#include "style/sources/source.hpp"
#include "style/light.hpp"
#include "snapshotter/map_snapshotter.hpp"
#include "snapshotter/map_snapshot.hpp"
@@ -161,7 +161,7 @@ void registerNatives(JavaVM *vm) {
// Style
TransitionOptions::registerNative(env);
registerNativeLayers(env);
registerNativeSources(env);
Source::registerNative(env);
Light::registerNative(env);
Position::registerNative(env);
Stop::registerNative(env);

View File

@@ -856,9 +856,7 @@ jni::Array<jni::Object<Source>> NativeMapView::getSources(JNIEnv& env) {
jni::Array<jni::Object<Source>> jSources = jni::Array<jni::Object<Source>>::New(env, sources.size(), Source::javaClass);
int index = 0;
for (auto source : sources) {
auto jSource = jni::Object<Source>(createJavaSourcePeer(env, *rendererFrontend, *source));
jSources.Set(env, index, jSource);
jni::DeleteLocalRef(env, jSource);
jSources.Set(env, index, Source::peerForCoreSource(env, *source, *rendererFrontend));
index++;
}
@@ -874,38 +872,25 @@ jni::Object<Source> NativeMapView::getSource(JNIEnv& env, jni::String sourceId)
}
// Create and return the source's native peer
return jni::Object<Source>(createJavaSourcePeer(env, *rendererFrontend, *coreSource));
return Source::peerForCoreSource(env, *coreSource, *rendererFrontend);
}
void NativeMapView::addSource(JNIEnv& env, jni::jlong sourcePtr) {
void NativeMapView::addSource(JNIEnv& env, jni::Object<Source> obj, jlong sourcePtr) {
assert(sourcePtr != 0);
Source *source = reinterpret_cast<Source *>(sourcePtr);
try {
source->addToMap(*map);
source->setRendererFrontend(*rendererFrontend);
source->addToMap(env, obj, *map, *rendererFrontend);
} catch (const std::runtime_error& error) {
jni::ThrowNew(env, jni::FindClass(env, "com/mapbox/mapboxsdk/style/sources/CannotAddSourceException"), error.what());
}
}
jni::Object<Source> NativeMapView::removeSourceById(JNIEnv& env, jni::String id) {
std::unique_ptr<mbgl::style::Source> coreSource = map->getStyle().removeSource(jni::Make<std::string>(env, id));
if (coreSource) {
return jni::Object<Source>(createJavaSourcePeer(env, *rendererFrontend, *coreSource));
} else {
return jni::Object<Source>();
}
}
void NativeMapView::removeSource(JNIEnv&, jlong sourcePtr) {
void NativeMapView::removeSource(JNIEnv& env, jni::Object<Source> obj, jlong sourcePtr) {
assert(sourcePtr != 0);
mbgl::android::Source *source = reinterpret_cast<mbgl::android::Source *>(sourcePtr);
std::unique_ptr<mbgl::style::Source> coreSource = map->getStyle().removeSource(source->get().getID());
if (coreSource) {
source->setSource(std::move(coreSource));
}
source->removeFromMap(env, obj, *map);
}
void NativeMapView::addImage(JNIEnv& env, jni::String name, jni::jint w, jni::jint h, jni::jfloat scale, jni::Array<jbyte> pixels) {
@@ -1048,7 +1033,6 @@ void NativeMapView::registerNative(jni::JNIEnv& env) {
METHOD(&NativeMapView::getSources, "nativeGetSources"),
METHOD(&NativeMapView::getSource, "nativeGetSource"),
METHOD(&NativeMapView::addSource, "nativeAddSource"),
METHOD(&NativeMapView::removeSourceById, "nativeRemoveSourceById"),
METHOD(&NativeMapView::removeSource, "nativeRemoveSource"),
METHOD(&NativeMapView::addImage, "nativeAddImage"),
METHOD(&NativeMapView::addImages, "nativeAddImages"),

View File

@@ -19,7 +19,7 @@
#include "geometry/lat_lng.hpp"
#include "geometry/projected_meters.hpp"
#include "style/layers/layers.hpp"
#include "style/sources/sources.hpp"
#include "style/sources/source.hpp"
#include "geometry/lat_lng_bounds.hpp"
#include "map/camera_position.hpp"
#include "map/image.hpp"
@@ -230,11 +230,11 @@ public:
jni::Object<Source> getSource(JNIEnv&, jni::String);
void addSource(JNIEnv&, jni::jlong);
void addSource(JNIEnv&, jni::Object<Source>, jlong nativePtr);
jni::Object<Source> removeSourceById(JNIEnv&, jni::String);
void removeSource(JNIEnv&, jlong);
void removeSource(JNIEnv&, jni::Object<Source>, jlong nativePtr);
void addImage(JNIEnv&, jni::String, jni::jint, jni::jint, jni::jfloat, jni::Array<jbyte>);

View File

@@ -46,6 +46,12 @@ namespace android {
javaPeer(_obj.NewGlobalRef(env)) {
}
CustomGeometrySource::CustomGeometrySource(jni::JNIEnv& env,
mbgl::style::Source& coreSource,
AndroidRendererFrontend& frontend)
: Source(env, coreSource, createJavaPeer(env), frontend) {
}
CustomGeometrySource::~CustomGeometrySource() = default;
void CustomGeometrySource::fetchTile (const mbgl::CanonicalTileID& tileID) {
@@ -94,9 +100,9 @@ namespace android {
jni::Class<CustomGeometrySource> CustomGeometrySource::javaClass;
jni::jobject* CustomGeometrySource::createJavaPeer(jni::JNIEnv& env) {
jni::Object<Source> CustomGeometrySource::createJavaPeer(jni::JNIEnv& env) {
static auto constructor = CustomGeometrySource::javaClass.template GetConstructor<jni::jlong>(env);
return CustomGeometrySource::javaClass.New(env, constructor, reinterpret_cast<jni::jlong>(this));
return jni::Object<Source>(CustomGeometrySource::javaClass.New(env, constructor, reinterpret_cast<jni::jlong>(this)).Get());
}
void CustomGeometrySource::registerNative(jni::JNIEnv& env) {

View File

@@ -27,6 +27,8 @@ public:
jni::String,
jni::Object<>);
CustomGeometrySource(jni::JNIEnv&, mbgl::style::Source&, AndroidRendererFrontend&);
~CustomGeometrySource();
void fetchTile(const mbgl::CanonicalTileID& tileID);
@@ -39,7 +41,8 @@ public:
jni::Array<jni::Object<geojson::Feature>> querySourceFeatures(jni::JNIEnv&,
jni::Array<jni::Object<>> );
jni::jobject* createJavaPeer(jni::JNIEnv&);
private:
jni::Object<Source> createJavaPeer(jni::JNIEnv&);
jni::UniqueObject<CustomGeometrySource> javaPeer;
}; // class CustomGeometrySource

View File

@@ -43,8 +43,10 @@ namespace android {
) {
}
GeoJSONSource::GeoJSONSource(mbgl::style::GeoJSONSource& coreSource)
: Source(coreSource) {
GeoJSONSource::GeoJSONSource(jni::JNIEnv& env,
mbgl::style::Source& coreSource,
AndroidRendererFrontend& frontend)
: Source(env, coreSource, createJavaPeer(env), frontend) {
}
GeoJSONSource::~GeoJSONSource() = default;
@@ -118,9 +120,9 @@ namespace android {
jni::Class<GeoJSONSource> GeoJSONSource::javaClass;
jni::jobject* GeoJSONSource::createJavaPeer(jni::JNIEnv& env) {
jni::Object<Source> GeoJSONSource::createJavaPeer(jni::JNIEnv& env) {
static auto constructor = GeoJSONSource::javaClass.template GetConstructor<jni::jlong>(env);
return GeoJSONSource::javaClass.New(env, constructor, reinterpret_cast<jni::jlong>(this));
return jni::Object<Source>(GeoJSONSource::javaClass.New(env, constructor, reinterpret_cast<jni::jlong>(this)).Get());
}
void GeoJSONSource::registerNative(jni::JNIEnv& env) {

View File

@@ -21,7 +21,7 @@ public:
GeoJSONSource(jni::JNIEnv&, jni::String, jni::Object<>);
GeoJSONSource(mbgl::style::GeoJSONSource&);
GeoJSONSource(jni::JNIEnv&, mbgl::style::Source&, AndroidRendererFrontend&);
~GeoJSONSource();
@@ -40,7 +40,8 @@ public:
jni::String getURL(jni::JNIEnv&);
jni::jobject* createJavaPeer(jni::JNIEnv&);
private:
jni::Object<Source> createJavaPeer(jni::JNIEnv&);
}; // class GeoJSONSource

View File

@@ -23,8 +23,10 @@ namespace android {
) {
}
ImageSource::ImageSource(mbgl::style::ImageSource& coreSource)
: Source(coreSource) {
ImageSource::ImageSource(jni::JNIEnv& env,
mbgl::style::Source& coreSource,
AndroidRendererFrontend& frontend)
: Source(env, coreSource, createJavaPeer(env), frontend) {
}
ImageSource::~ImageSource() = default;
@@ -45,9 +47,9 @@ namespace android {
jni::Class<ImageSource> ImageSource::javaClass;
jni::jobject* ImageSource::createJavaPeer(jni::JNIEnv& env) {
jni::Object<Source> ImageSource::createJavaPeer(jni::JNIEnv& env) {
static auto constructor = ImageSource::javaClass.template GetConstructor<jni::jlong>(env);
return ImageSource::javaClass.New(env, constructor, reinterpret_cast<jni::jlong>(this));
return jni::Object<Source>(ImageSource::javaClass.New(env, constructor, reinterpret_cast<jni::jlong>(this)).Get());
}
void ImageSource::registerNative(jni::JNIEnv& env) {

View File

@@ -21,7 +21,7 @@ public:
ImageSource(jni::JNIEnv&, jni::String, jni::Object<LatLngQuad>);
ImageSource(mbgl::style::ImageSource&);
ImageSource(jni::JNIEnv&, mbgl::style::Source&, AndroidRendererFrontend&);
~ImageSource();
@@ -30,7 +30,8 @@ public:
void setImage(jni::JNIEnv&, jni::Object<Bitmap>);
jni::jobject* createJavaPeer(jni::JNIEnv&);
private:
jni::Object<Source> createJavaPeer(jni::JNIEnv&);
}; // class ImageSource

View File

@@ -22,8 +22,10 @@ namespace android {
) {
}
RasterSource::RasterSource(mbgl::style::RasterSource& coreSource)
: Source(coreSource) {
RasterSource::RasterSource(jni::JNIEnv& env,
mbgl::style::Source& coreSource,
AndroidRendererFrontend& frontend)
: Source(env, coreSource, createJavaPeer(env), frontend) {
}
RasterSource::~RasterSource() = default;
@@ -35,9 +37,9 @@ namespace android {
jni::Class<RasterSource> RasterSource::javaClass;
jni::jobject* RasterSource::createJavaPeer(jni::JNIEnv& env) {
jni::Object<Source> RasterSource::createJavaPeer(jni::JNIEnv& env) {
static auto constructor = RasterSource::javaClass.template GetConstructor<jni::jlong>(env);
return RasterSource::javaClass.New(env, constructor, reinterpret_cast<jni::jlong>(this));
return jni::Object<Source>(RasterSource::javaClass.New(env, constructor, reinterpret_cast<jni::jlong>(this)).Get());
}
void RasterSource::registerNative(jni::JNIEnv& env) {

View File

@@ -18,13 +18,14 @@ public:
RasterSource(jni::JNIEnv&, jni::String, jni::Object<>, jni::jint);
RasterSource(mbgl::style::RasterSource&);
RasterSource(jni::JNIEnv&, mbgl::style::Source&, AndroidRendererFrontend&);
~RasterSource();
jni::String getURL(jni::JNIEnv&);
jni::jobject* createJavaPeer(jni::JNIEnv&);
private:
jni::Object<Source> createJavaPeer(jni::JNIEnv&);
}; // class RasterSource

View File

@@ -15,29 +15,70 @@
#include <string>
// Core Sources
#include <mbgl/style/sources/geojson_source.hpp>
#include <mbgl/style/sources/image_source.hpp>
#include <mbgl/style/sources/raster_source.hpp>
#include <mbgl/style/sources/vector_source.hpp>
// Android Source peers
#include "geojson_source.hpp"
#include "image_source.hpp"
#include "raster_source.hpp"
#include "unknown_source.hpp"
#include "vector_source.hpp"
#include "custom_geometry_source.hpp"
namespace mbgl {
namespace android {
/**
* Invoked when the construction is initiated from the jvm through a subclass
*/
static std::unique_ptr<Source> createSourcePeer(jni::JNIEnv& env, mbgl::style::Source& coreSource, AndroidRendererFrontend& frontend) {
if (coreSource.is<mbgl::style::VectorSource>()) {
return std::make_unique<VectorSource>(env, *coreSource.as<mbgl::style::VectorSource>(), frontend);
} else if (coreSource.is<mbgl::style::RasterSource>()) {
return std::make_unique<RasterSource>(env, *coreSource.as<mbgl::style::RasterSource>(), frontend);
} else if (coreSource.is<mbgl::style::GeoJSONSource>()) {
return std::make_unique<GeoJSONSource>(env, *coreSource.as<mbgl::style::GeoJSONSource>(), frontend);
} else if (coreSource.is<mbgl::style::ImageSource>()) {
return std::make_unique<ImageSource>(env, *coreSource.as<mbgl::style::ImageSource>(), frontend);
} else {
return std::make_unique<UnknownSource>(env, coreSource, frontend);
}
}
jni::Object<Source> Source::peerForCoreSource(jni::JNIEnv& env, mbgl::style::Source& coreSource, AndroidRendererFrontend& frontend) {
if (!coreSource.peer.has_value()) {
coreSource.peer = createSourcePeer(env, coreSource, frontend);
}
return *mbgl::util::any_cast<std::unique_ptr<Source>>(&coreSource.peer)->get()->javaPeer;
}
Source::Source(jni::JNIEnv& env, mbgl::style::Source& coreSource, jni::Object<Source> obj, AndroidRendererFrontend& frontend)
: source(coreSource)
, javaPeer(obj.NewGlobalRef(env))
, rendererFrontend(&frontend) {
}
Source::Source(jni::JNIEnv&, std::unique_ptr<mbgl::style::Source> coreSource)
: ownedSource(std::move(coreSource))
, source(*ownedSource) {
}
Source::Source(mbgl::style::Source& coreSource)
: source(coreSource) {
}
Source::~Source() = default;
style::Source& Source::get() {
return source;
}
void Source::setSource(std::unique_ptr<style::Source> coreSource) {
this->ownedSource = std::move(coreSource);
Source::~Source() {
// Before being added to a map, the Java peer owns this C++ peer and cleans
// up after itself correctly through the jni native peer bindings.
// After being added to the map, the ownership is flipped and the C++ peer has a strong reference
// to it's Java peer, preventing the Java peer from being GC'ed.
// In this case, the core source initiates the destruction, which requires releasing the Java peer,
// while also resetting it's nativePtr to 0 to prevent the subsequent GC of the Java peer from
// re-entering this dtor.
if (ownedSource.get() == nullptr && javaPeer.get() != nullptr) {
// Manually clear the java peer
android::UniqueEnv env = android::AttachEnv();
static auto nativePtrField = javaClass.GetField<jlong>(*env, "nativePtr");
javaPeer->Set(*env, nativePtrField, (jlong) 0);
javaPeer.reset();
}
}
jni::String Source::getId(jni::JNIEnv& env) {
@@ -49,23 +90,48 @@ namespace android {
return attribution ? jni::Make<jni::String>(env, attribution.value()) : jni::Make<jni::String>(env,"");
}
void Source::addToMap(mbgl::Map& _map) {
void Source::addToMap(JNIEnv& env, jni::Object<Source> obj, mbgl::Map& map, AndroidRendererFrontend& frontend) {
// Check to see if we own the source first
if (!ownedSource) {
throw std::runtime_error("Cannot add source twice");
}
// Add source to map
_map.getStyle().addSource(releaseCoreSource());
// Add source to map and release ownership
map.getStyle().addSource(std::move(ownedSource));
// Add peer to core source
source.peer = std::unique_ptr<Source>(this);
// Add strong reference to java source
javaPeer = obj.NewGlobalRef(env);
rendererFrontend = &frontend;
}
void Source::setRendererFrontend(AndroidRendererFrontend& frontend_) {
rendererFrontend = &frontend_;
}
void 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");
}
std::unique_ptr<mbgl::style::Source> Source::releaseCoreSource() {
assert(ownedSource != nullptr);
return std::move(ownedSource);
// Remove the source from the map and take ownership
ownedSource = map.getStyle().removeSource(source.getID());
// The source may not be removed if any layers still reference it
if (!ownedSource) {
return;
}
// Release the peer relationships. These will be re-established when the source is added to a map
assert(ownedSource->peer.has_value());
util::any_cast<std::unique_ptr<Source>>(&(ownedSource->peer))->release();
ownedSource->peer.reset();
// Release the strong reference to the java peer
assert(javaPeer);
javaPeer.release();
rendererFrontend = nullptr;
}
jni::Class<Source> Source::javaClass;
@@ -82,6 +148,13 @@ namespace android {
METHOD(&Source::getAttribution, "nativeGetAttribution")
);
// Register subclasses
GeoJSONSource::registerNative(env);
ImageSource::registerNative(env);
RasterSource::registerNative(env);
UnknownSource::registerNative(env);
VectorSource::registerNative(env);
CustomGeometrySource::registerNative(env);
}
} // namespace android

View File

@@ -21,48 +21,40 @@ public:
static void registerNative(jni::JNIEnv&);
/*
* Called when a Java object is created on the c++ side
*/
Source(mbgl::style::Source&);
static jni::Object<Source> peerForCoreSource(jni::JNIEnv&, mbgl::style::Source&, AndroidRendererFrontend&);
/*
* Called when a Java object was created from the jvm side
* Called when a Java object is created for a core source that belongs to a map.
*/
Source(jni::JNIEnv&, mbgl::style::Source&, jni::Object<Source>, AndroidRendererFrontend&);
/*
* Called when a Java object is created for a new core source that does not belong to a map.
*/
Source(jni::JNIEnv&, std::unique_ptr<mbgl::style::Source>);
virtual ~Source();
/**
* Set core source (ie return ownership after remove)
*/
void setSource(std::unique_ptr<style::Source>);
void addToMap(JNIEnv&, jni::Object<Source>, mbgl::Map&, AndroidRendererFrontend&);
style::Source& get();
void addToMap(mbgl::Map&);
void setRendererFrontend(AndroidRendererFrontend&);
virtual jni::jobject* createJavaPeer(jni::JNIEnv&) = 0;
void removeFromMap(JNIEnv&, jni::Object<Source>, mbgl::Map&);
jni::String getId(jni::JNIEnv&);
jni::String getAttribution(jni::JNIEnv&);
protected:
// Release the owned view and return it
std::unique_ptr<mbgl::style::Source> releaseCoreSource();
// Set on newly created sources until added to the map
// Set on newly created sources until added to the map.
std::unique_ptr<mbgl::style::Source> ownedSource;
// Raw pointer that is valid until the source is removed from the map
// Raw pointer that is valid at all times.
mbgl::style::Source& source;
// RendererFrontend pointer is valid only when
// added to the map
AndroidRendererFrontend* rendererFrontend;
// Set when the source is added to a map.
jni::UniqueObject<Source> javaPeer;
// RendererFrontend pointer is valid only when added to the map.
AndroidRendererFrontend* rendererFrontend { nullptr };
};
} // namespace android

View File

@@ -1,62 +0,0 @@
#include "sources.hpp"
#include <mbgl/style/source.hpp>
#include <mbgl/style/sources/geojson_source.hpp>
#include <mbgl/style/sources/image_source.hpp>
#include <mbgl/style/sources/raster_source.hpp>
#include <mbgl/style/sources/vector_source.hpp>
#include "source.hpp"
#include "geojson_source.hpp"
#include "image_source.hpp"
#include "raster_source.hpp"
#include "unknown_source.hpp"
#include "vector_source.hpp"
#include "custom_geometry_source.hpp"
namespace {
using namespace mbgl::android;
Source* initializeSourcePeer(mbgl::style::Source& coreSource) {
Source* source;
if (coreSource.is<mbgl::style::VectorSource>()) {
source = new VectorSource(*coreSource.as<mbgl::style::VectorSource>());
} else if (coreSource.is<mbgl::style::RasterSource>()) {
source = new RasterSource(*coreSource.as<mbgl::style::RasterSource>());
} else if (coreSource.is<mbgl::style::GeoJSONSource>()) {
source = new GeoJSONSource(*coreSource.as<mbgl::style::GeoJSONSource>());
} else if (coreSource.is<mbgl::style::ImageSource>()) {
source = new ImageSource(*coreSource.as<mbgl::style::ImageSource>());
} else {
source = new UnknownSource(coreSource);
}
return source;
}
} // namespace
namespace mbgl {
namespace android {
jni::jobject* createJavaSourcePeer(jni::JNIEnv& env, AndroidRendererFrontend& frontend, mbgl::style::Source& coreSource) {
std::unique_ptr<Source> peerSource = std::unique_ptr<Source>(initializeSourcePeer(coreSource));
peerSource->setRendererFrontend(frontend);
jni::jobject* result = peerSource->createJavaPeer(env);
peerSource.release();
return result;
}
void registerNativeSources(jni::JNIEnv& env) {
Source::registerNative(env);
GeoJSONSource::registerNative(env);
ImageSource::registerNative(env);
RasterSource::registerNative(env);
UnknownSource::registerNative(env);
VectorSource::registerNative(env);
CustomGeometrySource::registerNative(env);
}
}
}

View File

@@ -1,18 +0,0 @@
#pragma once
#include <mbgl/style/source.hpp>
#include "source.hpp"
#include "../../android_renderer_frontend.hpp"
#include <jni/jni.hpp>
namespace mbgl {
namespace android {
jni::jobject* createJavaSourcePeer(jni::JNIEnv&, AndroidRendererFrontend&, mbgl::style::Source&);
void registerNativeSources(jni::JNIEnv&);
} // namespace android
} // namespace mbgl

View File

@@ -12,15 +12,17 @@ namespace {
namespace mbgl {
namespace android {
UnknownSource::UnknownSource(mbgl::style::Source& coreSource)
: Source(coreSource) {
UnknownSource::UnknownSource(jni::JNIEnv& env,
mbgl::style::Source& coreSource,
AndroidRendererFrontend& frontend)
: Source(env, coreSource, createJavaPeer(env), frontend) {
}
jni::Class<UnknownSource> UnknownSource::javaClass;
jni::jobject* UnknownSource::createJavaPeer(jni::JNIEnv& env) {
jni::Object<Source> UnknownSource::createJavaPeer(jni::JNIEnv& env) {
static auto constructor = UnknownSource::javaClass.template GetConstructor<jni::jlong>(env);
return UnknownSource::javaClass.New(env, constructor, reinterpret_cast<jni::jlong>(this));
return jni::Object<Source>(UnknownSource::javaClass.New(env, constructor, reinterpret_cast<jni::jlong>(this)).Get());
}
void UnknownSource::registerNative(jni::JNIEnv& env) {

View File

@@ -16,11 +16,12 @@ public:
static void registerNative(jni::JNIEnv&);
UnknownSource(mbgl::style::Source&);
UnknownSource(jni::JNIEnv&, mbgl::style::Source&, AndroidRendererFrontend&);
~UnknownSource() = default;
jni::jobject* createJavaPeer(jni::JNIEnv&);
private:
jni::Object<Source> createJavaPeer(jni::JNIEnv&);
}; // class UnknownSource

View File

@@ -30,8 +30,10 @@ namespace android {
) {
}
VectorSource::VectorSource(mbgl::style::VectorSource& coreSource)
: Source(coreSource) {
VectorSource::VectorSource(jni::JNIEnv& env,
mbgl::style::Source& coreSource,
AndroidRendererFrontend& frontend)
: Source(env, coreSource, createJavaPeer(env), frontend) {
}
VectorSource::~VectorSource() = default;
@@ -56,9 +58,9 @@ namespace android {
jni::Class<VectorSource> VectorSource::javaClass;
jni::jobject* VectorSource::createJavaPeer(jni::JNIEnv& env) {
jni::Object<Source> VectorSource::createJavaPeer(jni::JNIEnv& env) {
static auto constructor = VectorSource::javaClass.template GetConstructor<jni::jlong>(env);
return VectorSource::javaClass.New(env, constructor, reinterpret_cast<jni::jlong>(this));
return jni::Object<Source>(VectorSource::javaClass.New(env, constructor, reinterpret_cast<jni::jlong>(this)).Get());
}
void VectorSource::registerNative(jni::JNIEnv& env) {

View File

@@ -19,7 +19,7 @@ public:
VectorSource(jni::JNIEnv&, jni::String, jni::Object<>);
VectorSource(mbgl::style::VectorSource&);
VectorSource(jni::JNIEnv&, mbgl::style::Source&, AndroidRendererFrontend&);
~VectorSource();
@@ -28,7 +28,8 @@ public:
jni::String getURL(jni::JNIEnv&);
jni::jobject* createJavaPeer(jni::JNIEnv&);
private:
jni::Object<Source> createJavaPeer(jni::JNIEnv&);
}; // class VectorSource