#android #c
#Android #c
Вопрос:
class SmartAttachCurrentThread
{
public:
SmartAttachCurrentThread(JavaVM *jvm, JNIEnv *env) : jvm(jvm), env(env)
{
//TODO: throw if jvm null?
jvm->AttachCurrentThread(amp;env, NULL);
}
~SmartAttachCurrentThread()
{
jvm->DetachCurrentThread();
}
private:
JNIEnv *env;
JavaVM *jvm;
};
Я пытаюсь создать интеллектуальный класс, который присоединяет текущий поток jni для меня и автоматически отсоединяется, поэтому я могу использовать так:
{
JNIEnv *env;
SmartAttachCurrentThread smartAttachCurrentThread(jvm, env);
jclass clazz;
clazz = env->FindClass("com/app/myapp/");
//call class method
//thread is detached here prevnting memory leak
}
Однако AttachCurrentThread
внутренняя SmartAttachCurrentThread
часть не изменит значение JNIEnv *env;
в строке
{
JNIEnv *env;
Что было бы хорошим решением для этого? Мне действительно нужен этот класс или я могу использовать std::unique_lock<T>
для какого-то типа T
, который делает то же самое?
Ответ №1:
Ваш конструктор класса принимает JNIEnv*
параметр по значению, поэтому env
переменная вне класса не обновляется. Вместо этого вам нужно передать его по ссылке, например:
class SmartAttachCurrentThread
{
public:
SmartAttachCurrentThread(JavaVM *jvm, JNIEnv* amp;env) : jvm(jvm)
{
if (!jvm)
throw ...; // whatever you want
if (jvm->AttachCurrentThread(amp;env, NULL) != JNI_OK)
throw ...; // whatever you want
}
~SmartAttachCurrentThread()
{
jvm->DetachCurrentThread();
}
private:
JavaVM *jvm;
};
...
{
JNIEnv *env;
SmartAttachCurrentThread smartAttachCurrentThread(jvm, env);
// now you can use env as needed...
}
Или передать его по указателю, например:
class SmartAttachCurrentThread
{
public:
SmartAttachCurrentThread(JavaVM *jvm, JNIEnv **env) : jvm(jvm)
{
if (!jvm || !env)
throw ...; // whatever you want
if (jvm->AttachCurrentThread(env, NULL) != JNI_OK)
throw ...; // whatever you want
}
~SmartAttachCurrentThread()
{
jvm->DetachCurrentThread();
}
private:
JavaVM *jvm;
};
...
{
JNIEnv *env;
SmartAttachCurrentThread smartAttachCurrentThread(jvm, amp;env);
// now you can use env as needed...
}