mirror of
https://codeberg.org/comaps/comaps
synced 2025-12-19 13:03:36 +00:00
[android] Hack to suppress most frequent crash on startup.
Signed-off-by: Viktor Govako <viktor.govako@gmail.com>
This commit is contained in:
committed by
Konstantin Pastbin
parent
6cccd32166
commit
98689fbbf8
@@ -29,7 +29,7 @@ JNIEXPORT void JNICALL Java_app_organicmaps_sdk_OrganicMaps_nativeInitFramework(
|
|||||||
{
|
{
|
||||||
if (!g_framework)
|
if (!g_framework)
|
||||||
{
|
{
|
||||||
g_framework = std::make_unique<android::Framework>([onComplete = jni::make_global_ref(onComplete)]()
|
g_framework = std::make_unique<android::Framework>([onComplete = jni::make_global_ref_safe(onComplete)]()
|
||||||
{
|
{
|
||||||
JNIEnv * env = jni::GetEnv();
|
JNIEnv * env = jni::GetEnv();
|
||||||
jmethodID const methodId = jni::GetMethodID(env, *onComplete, "run", "()V");
|
jmethodID const methodId = jni::GetMethodID(env, *onComplete, "run", "()V");
|
||||||
|
|||||||
@@ -98,18 +98,26 @@ JNIEXPORT void JNICALL JNI_OnUnload(JavaVM *, void *)
|
|||||||
|
|
||||||
namespace jni
|
namespace jni
|
||||||
{
|
{
|
||||||
JNIEnv * GetEnv()
|
JNIEnv * GetEnvSafe()
|
||||||
{
|
{
|
||||||
JNIEnv * env;
|
JNIEnv * env;
|
||||||
auto const res = g_jvm->GetEnv((void **)&env, JNI_VERSION_1_6);
|
auto const res = g_jvm->GetEnv((void **)&env, JNI_VERSION_1_6);
|
||||||
if (res != JNI_OK)
|
if (res != JNI_OK)
|
||||||
{
|
{
|
||||||
LOG(LERROR, ("Can't get JNIEnv. Is the thread attached to JVM?", res));
|
LOG(LERROR, ("Can't get JNIEnv. Is the thread attached to JVM?", res));
|
||||||
MYTHROW(RootException, ("Can't get JNIEnv. Is the thread attached to JVM?", res));
|
env = nullptr;
|
||||||
}
|
}
|
||||||
return env;
|
return env;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
JNIEnv * GetEnv()
|
||||||
|
{
|
||||||
|
JNIEnv * env = GetEnvSafe();
|
||||||
|
if (env == nullptr)
|
||||||
|
MYTHROW(RootException, ("Can't get JNIEnv. Is the thread attached to JVM?"));
|
||||||
|
return env;
|
||||||
|
}
|
||||||
|
|
||||||
JavaVM * GetJVM()
|
JavaVM * GetJVM()
|
||||||
{
|
{
|
||||||
ASSERT(g_jvm, ("JVM is not initialized"));
|
ASSERT(g_jvm, ("JVM is not initialized"));
|
||||||
@@ -218,6 +226,20 @@ std::shared_ptr<jobject> make_global_ref(jobject obj)
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// https://github.com/organicmaps/organicmaps/issues/9397
|
||||||
|
/// @todo There are no other ideas, let's try a safe version with a forever global ref ..
|
||||||
|
std::shared_ptr<jobject> make_global_ref_safe(jobject obj)
|
||||||
|
{
|
||||||
|
jobject * ref = new jobject(GetEnv()->NewGlobalRef(obj));
|
||||||
|
return std::shared_ptr<jobject>(ref, [](jobject * ref)
|
||||||
|
{
|
||||||
|
JNIEnv * env = GetEnvSafe();
|
||||||
|
if (env)
|
||||||
|
env->DeleteGlobalRef(*ref);
|
||||||
|
delete ref;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
std::string ToNativeString(JNIEnv * env, jthrowable const & e)
|
std::string ToNativeString(JNIEnv * env, jthrowable const & e)
|
||||||
{
|
{
|
||||||
jni::TScopedLocalClassRef logClassRef(env, env->FindClass("android/util/Log"));
|
jni::TScopedLocalClassRef logClassRef(env, env->FindClass("android/util/Log"));
|
||||||
|
|||||||
@@ -66,6 +66,8 @@ bool HandleJavaException(JNIEnv * env);
|
|||||||
base::LogLevel GetLogLevelForException(JNIEnv * env, jthrowable const & e);
|
base::LogLevel GetLogLevelForException(JNIEnv * env, jthrowable const & e);
|
||||||
|
|
||||||
std::shared_ptr<jobject> make_global_ref(jobject obj);
|
std::shared_ptr<jobject> make_global_ref(jobject obj);
|
||||||
|
std::shared_ptr<jobject> make_global_ref_safe(jobject obj);
|
||||||
|
|
||||||
using TScopedLocalRef = ScopedLocalRef<jobject>;
|
using TScopedLocalRef = ScopedLocalRef<jobject>;
|
||||||
using TScopedLocalClassRef = ScopedLocalRef<jclass>;
|
using TScopedLocalClassRef = ScopedLocalRef<jclass>;
|
||||||
using TScopedLocalObjectArrayRef = ScopedLocalRef<jobjectArray>;
|
using TScopedLocalObjectArrayRef = ScopedLocalRef<jobjectArray>;
|
||||||
|
|||||||
Reference in New Issue
Block a user