У меня есть метод вот такой метод
void setProfileTime(int iTime, const ProfileType &type)
{
JNIEnv *env = GetJniEnv();
// Put all the JNI values in a structure that is statically initalized on the
// first call to this method. This makes it thread safe in the unlikely case
// of multiple threads calling this method.
static struct JNIData
{
jclass helper_class;
jmethodID load_image_method;
}
jniIds = [env]() -> JNIData {
constexpr char kHelperClassName[] = "com/my_custom_class/ar/JniInterface";
constexpr char kLoadImageMethodName[] = "loadImagee";
constexpr char kLoadImageMethodSignature[] = "(Ljava/lang/String;)Ljava/lang/String;";
jclass helper_class = FindClass(kHelperClassName);
if (helper_class)
{
helper_class = static_cast<jclass>(env->NewGlobalRef(helper_class));
jmethodID load_image_method = env->GetStaticMethodID(
helper_class, kLoadImageMethodName, kLoadImageMethodSignature);
return {helper_class, load_image_method};
}
LOGE("my_custom_class::util::Could not find Java helper class %s",
kHelperClassName);
return {};
}();
if (!jniIds.helper_class)
{
return;
}
jstring j_path = env->NewStringUTF(std::to_string(4).c_str());
jobject image_obj = env->CallStaticObjectMethod(jniIds.helper_class, jniIds.load_image_method, j_path);
}
Я вызываю его из cpp когда мне нужно обратиться к Java классам
Проблема в том, что когда я вызываю этот метод из одного потока (UI) все работает, когда я вызываю этот метод из другого созданного cpp потока, то получаю NULL в это строке
jclass helper_class = FindClass(kHelperClassName);
Не пойму в чем может быть причина...
Кто работал с JNI скажите это номальное поведение?
EDIT1
Метод который возвращает JNIEnv
JNIEnv *GetJniEnv()
{
JNIEnv *env;
jint result = g_vm->AttachCurrentThread(&env, nullptr);
return result == JNI_OK ? env : nullptr;
}
EDIT2
Мой JNI_OnLoad() метод
jint JNI_OnLoad(JavaVM *vm, void *)
{
g_vm = vm;
return JNI_VERSION_1_6;
}
Мой FindClass() метод
jclass FindClass(const char *classname)
{
JNIEnv *env = GetJniEnv();
return env->FindClass(classname);
}
Из документации:
You can get into trouble if you create a thread yourself (perhaps by
calling pthread_create and then attaching it with
AttachCurrentThread). Now there are no stack frames from your
application. If you call FindClass from this thread, the JavaVM will
start in the "system" class loader instead of the one associated with
your application, so attempts to find app-specific classes will fail.
There are a few ways to work around this:
FindClass lookups once, in JNI_OnLoad, and cache the class references for later use. Any FindClass calls made as part of
executing JNI_OnLoad will use the class loader associated with the
function that called System.loadLibrary (this is a special rule,
provided to make library initialization more convenient). If your app
code is loading the library, FindClass will use the correct class
loader.Продвижение своими сайтами как стратегия роста и независимости