diff --git a/platform/android/api/jni_singleton.h b/platform/android/api/jni_singleton.h
index 5b30c392e7f..01da0c79351 100644
--- a/platform/android/api/jni_singleton.h
+++ b/platform/android/api/jni_singleton.h
@@ -244,6 +244,7 @@ public:
~JNISingleton() {
#ifdef ANDROID_ENABLED
+ method_map.clear();
if (instance) {
JNIEnv *env = get_jni_env();
ERR_FAIL_NULL(env);
diff --git a/platform/android/java/lib/src/org/godotengine/godot/plugin/GodotPlugin.java b/platform/android/java/lib/src/org/godotengine/godot/plugin/GodotPlugin.java
index c0912ca4dcc..c975c29e969 100644
--- a/platform/android/java/lib/src/org/godotengine/godot/plugin/GodotPlugin.java
+++ b/platform/android/java/lib/src/org/godotengine/godot/plugin/GodotPlugin.java
@@ -112,19 +112,18 @@ public abstract class GodotPlugin {
/**
* Register the plugin with Godot native code.
*
- * This method is invoked by the Godot Engine on the render thread.
+ * This method is invoked on the render thread to register the plugin on engine startup.
*/
public final void onRegisterPluginWithGodotNative() {
- registeredSignals.putAll(
- registerPluginWithGodotNative(this, getPluginName(), getPluginMethods(), getPluginSignals()));
- }
+ final String pluginName = getPluginName();
+ if (!nativeRegisterSingleton(pluginName, this)) {
+ return;
+ }
- private static Map registerPluginWithGodotNative(Object pluginObject,
- String pluginName, List pluginMethods, Set pluginSignals) {
- nativeRegisterSingleton(pluginName, pluginObject);
+ List pluginMethods = getPluginMethods();
Set filteredMethods = new HashSet<>();
- Class> clazz = pluginObject.getClass();
+ Class> clazz = getClass();
Method[] methods = clazz.getDeclaredMethods();
for (Method method : methods) {
@@ -156,15 +155,14 @@ public abstract class GodotPlugin {
nativeRegisterMethod(pluginName, method.getName(), method.getReturnType().getName(), pt);
}
+ Set pluginSignals = getPluginSignals();
+
// Register the signals for this plugin.
- Map registeredSignals = new HashMap<>();
for (SignalInfo signalInfo : pluginSignals) {
String signalName = signalInfo.getName();
nativeRegisterSignal(pluginName, signalName, signalInfo.getParamTypesNames());
registeredSignals.put(signalName, signalInfo);
}
-
- return registeredSignals;
}
/**
@@ -408,7 +406,7 @@ public abstract class GodotPlugin {
* Used to setup a {@link GodotPlugin} instance.
* @param p_name Name of the instance.
*/
- private static native void nativeRegisterSingleton(String p_name, Object object);
+ private static native boolean nativeRegisterSingleton(String p_name, Object object);
/**
* Used to complete registration of the {@link GodotPlugin} instance's methods.
diff --git a/platform/android/java/nativeSrcsConfigs/CMakeLists.txt b/platform/android/java/nativeSrcsConfigs/CMakeLists.txt
index e1534c7685d..96b6dfc9f38 100644
--- a/platform/android/java/nativeSrcsConfigs/CMakeLists.txt
+++ b/platform/android/java/nativeSrcsConfigs/CMakeLists.txt
@@ -7,6 +7,7 @@ set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)
set(GODOT_ROOT_DIR ../../../..)
+set(ANDROID_ROOT_DIR "${GODOT_ROOT_DIR}/platform/android" CACHE STRING "")
# Get sources
file(GLOB_RECURSE SOURCES ${GODOT_ROOT_DIR}/*.c**)
@@ -15,6 +16,7 @@ file(GLOB_RECURSE HEADERS ${GODOT_ROOT_DIR}/*.h**)
add_executable(${PROJECT_NAME} ${SOURCES} ${HEADERS})
target_include_directories(${PROJECT_NAME}
SYSTEM PUBLIC
- ${GODOT_ROOT_DIR})
+ ${GODOT_ROOT_DIR}
+ ${ANDROID_ROOT_DIR})
add_definitions(-DUNIX_ENABLED -DVULKAN_ENABLED -DANDROID_ENABLED -DGLES3_ENABLED -DTOOLS_ENABLED)
diff --git a/platform/android/java_godot_lib_jni.cpp b/platform/android/java_godot_lib_jni.cpp
index 6cab7e74fd2..93743c4e35f 100644
--- a/platform/android/java_godot_lib_jni.cpp
+++ b/platform/android/java_godot_lib_jni.cpp
@@ -42,6 +42,7 @@
#include "jni_utils.h"
#include "net_socket_android.h"
#include "os_android.h"
+#include "plugin/godot_plugin_jni.h"
#include "string_android.h"
#include "thread_jandroid.h"
#include "tts_android.h"
@@ -78,6 +79,9 @@ static void _terminate(JNIEnv *env, bool p_restart = false) {
step.set(-1); // Ensure no further steps are attempted and no further events are sent
// lets cleanup
+ // Unregister android plugins
+ unregister_plugins_singletons();
+
if (java_class_wrapper) {
memdelete(java_class_wrapper);
}
diff --git a/platform/android/plugin/godot_plugin_jni.cpp b/platform/android/plugin/godot_plugin_jni.cpp
index fd60ba4ae71..e3cde145cb6 100644
--- a/platform/android/plugin/godot_plugin_jni.cpp
+++ b/platform/android/plugin/godot_plugin_jni.cpp
@@ -40,16 +40,32 @@
static HashMap jni_singletons;
+void unregister_plugins_singletons() {
+ for (const KeyValue &E : jni_singletons) {
+ Engine::get_singleton()->remove_singleton(E.key);
+ ProjectSettings::get_singleton()->set(E.key, Variant());
+
+ if (E.value) {
+ memdelete(E.value);
+ }
+ }
+ jni_singletons.clear();
+}
+
extern "C" {
-JNIEXPORT void JNICALL Java_org_godotengine_godot_plugin_GodotPlugin_nativeRegisterSingleton(JNIEnv *env, jclass clazz, jstring name, jobject obj) {
+JNIEXPORT jboolean JNICALL Java_org_godotengine_godot_plugin_GodotPlugin_nativeRegisterSingleton(JNIEnv *env, jclass clazz, jstring name, jobject obj) {
String singname = jstring_to_string(name, env);
+
+ ERR_FAIL_COND_V(jni_singletons.has(singname), false);
+
JNISingleton *s = (JNISingleton *)ClassDB::instantiate("JNISingleton");
s->set_instance(env->NewGlobalRef(obj));
jni_singletons[singname] = s;
Engine::get_singleton()->add_singleton(Engine::Singleton(singname, s));
ProjectSettings::get_singleton()->set(singname, s);
+ return true;
}
JNIEXPORT void JNICALL Java_org_godotengine_godot_plugin_GodotPlugin_nativeRegisterMethod(JNIEnv *env, jclass clazz, jstring sname, jstring name, jstring ret, jobjectArray args) {
diff --git a/platform/android/plugin/godot_plugin_jni.h b/platform/android/plugin/godot_plugin_jni.h
index baa29a79ea2..8c62fb0f688 100644
--- a/platform/android/plugin/godot_plugin_jni.h
+++ b/platform/android/plugin/godot_plugin_jni.h
@@ -34,8 +34,10 @@
#include
#include
+void unregister_plugins_singletons();
+
extern "C" {
-JNIEXPORT void JNICALL Java_org_godotengine_godot_plugin_GodotPlugin_nativeRegisterSingleton(JNIEnv *env, jclass clazz, jstring name, jobject obj);
+JNIEXPORT jboolean JNICALL Java_org_godotengine_godot_plugin_GodotPlugin_nativeRegisterSingleton(JNIEnv *env, jclass clazz, jstring name, jobject obj);
JNIEXPORT void JNICALL Java_org_godotengine_godot_plugin_GodotPlugin_nativeRegisterMethod(JNIEnv *env, jclass clazz, jstring sname, jstring name, jstring ret, jobjectArray args);
JNIEXPORT void JNICALL Java_org_godotengine_godot_plugin_GodotPlugin_nativeRegisterSignal(JNIEnv *env, jclass clazz, jstring j_plugin_name, jstring j_signal_name, jobjectArray j_signal_param_types);
JNIEXPORT void JNICALL Java_org_godotengine_godot_plugin_GodotPlugin_nativeEmitSignal(JNIEnv *env, jclass clazz, jstring j_plugin_name, jstring j_signal_name, jobjectArray j_signal_params);