diff options
Diffstat (limited to 'src/corelib/kernel/qjni.cpp')
-rw-r--r-- | src/corelib/kernel/qjni.cpp | 58 |
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 |