Refactor duplicate code for clearing JNI exceptions before returning
Add a private function to handle checking/clearing and deleting the local reference to jobject before returning a QJniObject. Task-number: QTBUG-89633 Pick-to: 6.1 Change-Id: I0ea28c8ba4da0bfc1e341c6b4c1f61fecfec87a6 Reviewed-by: Ville Voutilainen <ville.voutilainen@qt.io>
This commit is contained in:
parent
deca7cd730
commit
c7bcc51e2c
@ -716,6 +716,27 @@ QJniObject::QJniObject(jobject obj)
|
|||||||
env->DeleteLocalRef(cls);
|
env->DeleteLocalRef(cls);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\brief Get a JNI object from a jobject variant and do the necessary
|
||||||
|
exception clearing and delete the local reference before returning.
|
||||||
|
The JNI object can be null if there was an exception.
|
||||||
|
*/
|
||||||
|
inline static QJniObject getCleanJniObject(jobject obj)
|
||||||
|
{
|
||||||
|
if (!obj)
|
||||||
|
return QJniObject();
|
||||||
|
|
||||||
|
QJniEnvironment env;
|
||||||
|
if (env.exceptionCheckAndClear()) {
|
||||||
|
env->DeleteLocalRef(obj);
|
||||||
|
return QJniObject();
|
||||||
|
}
|
||||||
|
|
||||||
|
QJniObject res(obj);
|
||||||
|
env->DeleteLocalRef(obj);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
\fn QJniObject::~QJniObject()
|
\fn QJniObject::~QJniObject()
|
||||||
|
|
||||||
@ -797,19 +818,11 @@ QJniObject QJniObject::callStaticObjectMethodV(jclass clazz,
|
|||||||
va_list args)
|
va_list args)
|
||||||
{
|
{
|
||||||
QJniEnvironment env;
|
QJniEnvironment env;
|
||||||
jobject res = nullptr;
|
|
||||||
jmethodID id = getMethodID(env, clazz, methodName, signature, true);
|
jmethodID id = getMethodID(env, clazz, methodName, signature, true);
|
||||||
if (id) {
|
if (!id)
|
||||||
res = env->CallStaticObjectMethodV(clazz, id, args);
|
return QJniObject();
|
||||||
if (env.exceptionCheckAndClear()) {
|
|
||||||
env->DeleteLocalRef(res);
|
|
||||||
res = nullptr;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
QJniObject obj(res);
|
return getCleanJniObject(env->CallStaticObjectMethodV(clazz, id, args));
|
||||||
env->DeleteLocalRef(res);
|
|
||||||
return obj;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@ -1150,22 +1163,16 @@ DECLARE_JNI_METHODS(Double, jdouble, "()D")
|
|||||||
QJniObject QJniObject::callObjectMethod(const char *methodName, const char *signature, ...) const
|
QJniObject QJniObject::callObjectMethod(const char *methodName, const char *signature, ...) const
|
||||||
{
|
{
|
||||||
QJniEnvironment env;
|
QJniEnvironment env;
|
||||||
jobject res = nullptr;
|
|
||||||
jmethodID id = getCachedMethodID(env, d->m_jclass, d->m_className, methodName, signature);
|
jmethodID id = getCachedMethodID(env, d->m_jclass, d->m_className, methodName, signature);
|
||||||
if (id) {
|
if (id) {
|
||||||
va_list args;
|
va_list args;
|
||||||
va_start(args, signature);
|
va_start(args, signature);
|
||||||
res = env->CallObjectMethodV(d->m_jobject, id, args);
|
QJniObject res = getCleanJniObject(env->CallObjectMethodV(d->m_jobject, id, args));
|
||||||
va_end(args);
|
va_end(args);
|
||||||
if (env.exceptionCheckAndClear()) {
|
return res;
|
||||||
env->DeleteLocalRef(res);
|
|
||||||
res = nullptr;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QJniObject obj(res);
|
return QJniObject();
|
||||||
env->DeleteLocalRef(res);
|
|
||||||
return obj;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@ -1187,7 +1194,6 @@ QJniObject QJniObject::callStaticObjectMethod(const char *className,
|
|||||||
...)
|
...)
|
||||||
{
|
{
|
||||||
QJniEnvironment env;
|
QJniEnvironment env;
|
||||||
jobject res = nullptr;
|
|
||||||
jclass clazz = loadClass(className, env);
|
jclass clazz = loadClass(className, env);
|
||||||
if (clazz) {
|
if (clazz) {
|
||||||
jmethodID id = getCachedMethodID(env, clazz, toBinaryEncClassName(className),
|
jmethodID id = getCachedMethodID(env, clazz, toBinaryEncClassName(className),
|
||||||
@ -1195,18 +1201,13 @@ QJniObject QJniObject::callStaticObjectMethod(const char *className,
|
|||||||
if (id) {
|
if (id) {
|
||||||
va_list args;
|
va_list args;
|
||||||
va_start(args, signature);
|
va_start(args, signature);
|
||||||
res = env->CallStaticObjectMethodV(clazz, id, args);
|
QJniObject res = getCleanJniObject(env->CallStaticObjectMethodV(clazz, id, args));
|
||||||
va_end(args);
|
va_end(args);
|
||||||
if (env.exceptionCheckAndClear()) {
|
return res;
|
||||||
env->DeleteLocalRef(res);
|
|
||||||
res = nullptr;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
QJniObject obj(res);
|
return QJniObject();
|
||||||
env->DeleteLocalRef(res);
|
|
||||||
return obj;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@ -1221,23 +1222,18 @@ QJniObject QJniObject::callStaticObjectMethod(jclass clazz,
|
|||||||
...)
|
...)
|
||||||
{
|
{
|
||||||
QJniEnvironment env;
|
QJniEnvironment env;
|
||||||
jobject res = nullptr;
|
|
||||||
if (clazz) {
|
if (clazz) {
|
||||||
jmethodID id = getMethodID(env, clazz, methodName, signature, true);
|
jmethodID id = getMethodID(env, clazz, methodName, signature, true);
|
||||||
if (id) {
|
if (id) {
|
||||||
va_list args;
|
va_list args;
|
||||||
va_start(args, signature);
|
va_start(args, signature);
|
||||||
res = env->CallStaticObjectMethodV(clazz, id, args);
|
QJniObject res = getCleanJniObject(env->CallStaticObjectMethodV(clazz, id, args));
|
||||||
va_end(args);
|
va_end(args);
|
||||||
if (env.exceptionCheckAndClear()) {
|
return res;
|
||||||
env->DeleteLocalRef(res);
|
|
||||||
res = nullptr;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
QJniObject obj(res);
|
|
||||||
env->DeleteLocalRef(res);
|
return QJniObject();
|
||||||
return obj;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@ -1534,15 +1530,7 @@ QJniObject QJniObject::getStaticObjectField(const char *className,
|
|||||||
if (!id)
|
if (!id)
|
||||||
return QJniObject();
|
return QJniObject();
|
||||||
|
|
||||||
jobject res = env->GetStaticObjectField(clazz, id);
|
return getCleanJniObject(env->GetStaticObjectField(clazz, id));
|
||||||
if (env.exceptionCheckAndClear()) {
|
|
||||||
env->DeleteLocalRef(res);
|
|
||||||
res = nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
QJniObject obj(res);
|
|
||||||
env->DeleteLocalRef(res);
|
|
||||||
return obj;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@ -1562,19 +1550,11 @@ QJniObject QJniObject::getStaticObjectField(jclass clazz,
|
|||||||
const char *signature)
|
const char *signature)
|
||||||
{
|
{
|
||||||
QJniEnvironment env;
|
QJniEnvironment env;
|
||||||
jobject res = nullptr;
|
|
||||||
jfieldID id = getFieldID(env, clazz, fieldName, signature, true);
|
jfieldID id = getFieldID(env, clazz, fieldName, signature, true);
|
||||||
if (id) {
|
if (!id)
|
||||||
res = env->GetStaticObjectField(clazz, id);
|
return QJniObject();
|
||||||
if (env.exceptionCheckAndClear()) {
|
|
||||||
env->DeleteLocalRef(res);
|
|
||||||
res = nullptr;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
QJniObject obj(res);
|
return getCleanJniObject(env->GetStaticObjectField(clazz, id));
|
||||||
env->DeleteLocalRef(res);
|
|
||||||
return obj;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@ -1693,19 +1673,11 @@ void QJniObject::setField<jobjectArray>(const char *fieldName,
|
|||||||
QJniObject QJniObject::getObjectField(const char *fieldName, const char *signature) const
|
QJniObject QJniObject::getObjectField(const char *fieldName, const char *signature) const
|
||||||
{
|
{
|
||||||
QJniEnvironment env;
|
QJniEnvironment env;
|
||||||
jobject res = nullptr;
|
|
||||||
jfieldID id = getCachedFieldID(env, d->m_jclass, d->m_className, fieldName, signature);
|
jfieldID id = getCachedFieldID(env, d->m_jclass, d->m_className, fieldName, signature);
|
||||||
if (id) {
|
if (!id)
|
||||||
res = env->GetObjectField(d->m_jobject, id);
|
return QJniObject();
|
||||||
if (env.exceptionCheckAndClear()) {
|
|
||||||
env->DeleteLocalRef(res);
|
|
||||||
res = nullptr;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
QJniObject obj(res);
|
return getCleanJniObject(env->GetObjectField(d->m_jobject, id));
|
||||||
env->DeleteLocalRef(res);
|
|
||||||
return obj;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@ -1802,17 +1774,8 @@ DECLARE_JNI_OBJECT_FILEDS(jdoubleArray, "[D")
|
|||||||
QJniObject QJniObject::fromString(const QString &string)
|
QJniObject QJniObject::fromString(const QString &string)
|
||||||
{
|
{
|
||||||
QJniEnvironment env;
|
QJniEnvironment env;
|
||||||
jstring res = env->NewString(reinterpret_cast<const jchar*>(string.constData()),
|
return getCleanJniObject(env->NewString(reinterpret_cast<const jchar*>(string.constData()),
|
||||||
string.length());
|
string.length()));
|
||||||
|
|
||||||
if (env.exceptionCheckAndClear()) {
|
|
||||||
env->DeleteLocalRef(res);
|
|
||||||
res = nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
QJniObject obj(res);
|
|
||||||
env->DeleteLocalRef(res);
|
|
||||||
return obj;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
|
Loading…
Reference in New Issue
Block a user