summaryrefslogtreecommitdiffstats
path: root/src/corelib/kernel/qjni.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/corelib/kernel/qjni.cpp')
-rw-r--r--src/corelib/kernel/qjni.cpp58
1 files changed, 35 insertions, 23 deletions
diff --git a/src/corelib/kernel/qjni.cpp b/src/corelib/kernel/qjni.cpp
index 54cd2b5a75..4e06d12aee 100644
--- a/src/corelib/kernel/qjni.cpp
+++ b/src/corelib/kernel/qjni.cpp
@@ -162,24 +162,31 @@ static jfieldID getCachedFieldID(JNIEnv *env,
return id;
}
-Q_GLOBAL_STATIC(QThreadStorage<int>, refCount)
+class QJNIEnvironmentPrivateTLS
+{
+public:
+ inline ~QJNIEnvironmentPrivateTLS()
+ {
+ QtAndroidPrivate::javaVM()->DetachCurrentThread();
+ }
+};
+
+Q_GLOBAL_STATIC(QThreadStorage<QJNIEnvironmentPrivateTLS *>, jniEnvTLS)
QJNIEnvironmentPrivate::QJNIEnvironmentPrivate()
: jniEnv(0)
{
JavaVM *vm = QtAndroidPrivate::javaVM();
if (vm->GetEnv((void**)&jniEnv, JNI_VERSION_1_6) == JNI_EDETACHED) {
- if (vm->AttachCurrentThread(&jniEnv, 0) < 0)
+ if (vm->AttachCurrentThread(&jniEnv, 0) != JNI_OK)
return;
}
if (!jniEnv)
return;
- if (!refCount->hasLocalData())
- refCount->setLocalData(1);
- else
- refCount->setLocalData(refCount->localData() + 1);
+ if (!jniEnvTLS->hasLocalData())
+ jniEnvTLS->setLocalData(new QJNIEnvironmentPrivateTLS);
}
JNIEnv *QJNIEnvironmentPrivate::operator->()
@@ -194,16 +201,6 @@ QJNIEnvironmentPrivate::operator JNIEnv* () const
QJNIEnvironmentPrivate::~QJNIEnvironmentPrivate()
{
- if (!jniEnv)
- return;
-
- const int newRef = refCount->localData() - 1;
- refCount->setLocalData(newRef);
-
- if (newRef == 0)
- QtAndroidPrivate::javaVM()->DetachCurrentThread();
-
- jniEnv = 0;
}
QJNIObjectData::QJNIObjectData()
@@ -354,7 +351,9 @@ QJNIObjectPrivate::QJNIObjectPrivate(jobject obj)
QJNIEnvironmentPrivate env;
d->m_jobject = env->NewGlobalRef(obj);
- d->m_jclass = static_cast<jclass>(env->NewGlobalRef(env->GetObjectClass(d->m_jobject)));
+ jclass objectClass = env->GetObjectClass(d->m_jobject);
+ d->m_jclass = static_cast<jclass>(env->NewGlobalRef(objectClass));
+ env->DeleteLocalRef(objectClass);
}
template <>
@@ -1265,7 +1264,10 @@ QJNIObjectPrivate QJNIObjectPrivate::callObjectMethod(const char *methodName,
if (id) {
res = env->CallObjectMethodV(d->m_jobject, id, args);
}
- return res;
+
+ QJNIObjectPrivate obj(res);
+ env->DeleteLocalRef(res);
+ return obj;
}
QJNIObjectPrivate QJNIObjectPrivate::callObjectMethod(const char *methodName,
@@ -1342,7 +1344,9 @@ QJNIObjectPrivate QJNIObjectPrivate::callStaticObjectMethod(const char *classNam
}
}
- return res;
+ QJNIObjectPrivate obj(res);
+ env->DeleteLocalRef(res);
+ return obj;
}
QJNIObjectPrivate QJNIObjectPrivate::callStaticObjectMethod(const char *className,
@@ -1369,7 +1373,9 @@ QJNIObjectPrivate QJNIObjectPrivate::callStaticObjectMethod(jclass clazz,
res = env->CallStaticObjectMethodV(clazz, id, args);
}
- return res;
+ QJNIObjectPrivate obj(res);
+ env->DeleteLocalRef(res);
+ return obj;
}
QJNIObjectPrivate QJNIObjectPrivate::callStaticObjectMethod(jclass clazz,
@@ -1681,7 +1687,9 @@ QJNIObjectPrivate QJNIObjectPrivate::getObjectField(const char *fieldName,
if (id)
res = env->GetObjectField(d->m_jobject, id);
- return res;
+ QJNIObjectPrivate obj(res);
+ env->DeleteLocalRef(res);
+ return obj;
}
QJNIObjectPrivate QJNIObjectPrivate::getStaticObjectField(const char *className,
@@ -1707,7 +1715,9 @@ QJNIObjectPrivate QJNIObjectPrivate::getStaticObjectField(jclass clazz,
if (id)
res = env->GetStaticObjectField(clazz, id);
- return res;
+ QJNIObjectPrivate obj(res);
+ env->DeleteLocalRef(res);
+ return obj;
}
template <>
@@ -2109,7 +2119,9 @@ QJNIObjectPrivate QJNIObjectPrivate::fromString(const QString &string)
QJNIEnvironmentPrivate env;
jstring res = env->NewString(reinterpret_cast<const jchar*>(string.constData()),
string.length());
- return res;
+ QJNIObjectPrivate obj(res);
+ env->DeleteLocalRef(res);
+ return obj;
}
QString QJNIObjectPrivate::toString() const