JNI: Add calls to get field IDs

Task-number: QTBUG-92952
Change-Id: Ie68ede4b00a411064a29925b28b1f60a84d2d678
Reviewed-by: Ivan Solovev <ivan.solovev@qt.io>
Reviewed-by: Ville Voutilainen <ville.voutilainen@qt.io>
This commit is contained in:
Assam Boudjelthia 2021-06-01 18:32:05 +03:00
parent dc794f7622
commit 965fc1148d
4 changed files with 100 additions and 0 deletions

View File

@ -255,6 +255,51 @@ jmethodID QJniEnvironment::findStaticMethod(jclass clazz, const char *methodName
return id;
}
/*!
Searches for an member field of a class \a clazz. The field is specified
by its \a fieldName and \a signature.
Returns the field ID or \c nullptr if the field is not found.
A usecase for this method is searching for class fields and caching their
IDs, so that they could later be used for getting/setting the fields.
\since 6.2
*/
jfieldID QJniEnvironment::findField(jclass clazz, const char *fieldName, const char *signature)
{
if (clazz) {
jfieldID id = d->jniEnv->GetFieldID(clazz, fieldName, signature);
if (!checkAndClearExceptions())
return id;
}
return nullptr;
}
/*!
Searches for a static field of a class \a clazz. The field is specified
by its \a fieldName and \a signature.
Returns the field ID or \c nullptr if the field is not found.
A usecase for this method is searching for class fields and caching their
IDs, so that they could later be used for getting/setting the fields.
\since 6.2
*/
jfieldID QJniEnvironment::findStaticField(jclass clazz, const char *fieldName, const char *signature)
{
if (clazz) {
jfieldID id = d->jniEnv->GetStaticFieldID(clazz, fieldName, signature);
if (!checkAndClearExceptions())
return id;
}
return nullptr;
}
/*!
\fn JavaVM *QJniEnvironment::javaVM()

View File

@ -61,6 +61,8 @@ public:
jclass findClass(const char *className);
jmethodID findMethod(jclass clazz, const char *methodName, const char *signature);
jmethodID findStaticMethod(jclass clazz, const char *methodName, const char *signature);
jfieldID findField(jclass clazz, const char *fieldName, const char *signature);
jfieldID findStaticField(jclass clazz, const char *fieldName, const char *signature);
static JavaVM *javaVM();
bool registerNativeMethods(const char *className, const JNINativeMethod methods[], int size);
bool registerNativeMethods(jclass clazz, const JNINativeMethod methods[], int size);

View File

@ -33,6 +33,11 @@ public class QtJniEnvironmentTestClass
private static native void callbackFromJava(String message);
private static native void intCallbackFromJava(int value);
public final int INT_FIELD = 123;
public static final int S_INT_FIELD = 321;
QtJniEnvironmentTestClass() {}
public static void appendJavaToString(String message)
{
callbackFromJava("From Java: " + message);

View File

@ -49,6 +49,8 @@ private slots:
void registerNativeMethodsByJclass();
void findMethod();
void findStaticMethod();
void findField();
void findStaticField();
};
void tst_QJniEnvironment::jniEnv()
@ -203,6 +205,52 @@ void tst_QJniEnvironment::findStaticMethod()
QVERIFY(!env.checkAndClearExceptions());
}
void tst_QJniEnvironment::findField()
{
QJniEnvironment env;
jclass clazz = env.findClass(javaTestClass);
QVERIFY(clazz != nullptr);
// valid field
jfieldID validId = env.findField(clazz, "INT_FIELD", "I");
QVERIFY(validId != nullptr);
jmethodID constructorId = env.findMethod(clazz, "<init>", "()V");
QVERIFY(constructorId != nullptr);
jobject obj = env->NewObject(clazz, constructorId);
QVERIFY(!env.checkAndClearExceptions());
int value = env->GetIntField(obj, validId);
QVERIFY(!env.checkAndClearExceptions());
QVERIFY(value == 123);
// invalid signature
jfieldID invalidId = env.findField(clazz, "unknown", "I");
QVERIFY(invalidId == nullptr);
// check that all exceptions are already cleared
QVERIFY(!env.checkAndClearExceptions());
}
void tst_QJniEnvironment::findStaticField()
{
QJniEnvironment env;
jclass clazz = env.findClass(javaTestClass);
QVERIFY(clazz != nullptr);
// valid field
jfieldID validId = env.findStaticField(clazz, "S_INT_FIELD", "I");
QVERIFY(validId != nullptr);
int size = env->GetStaticIntField(clazz, validId);
QVERIFY(!env.checkAndClearExceptions());
QVERIFY(size == 321);
// invalid signature
jfieldID invalidId = env.findStaticField(clazz, "unknown", "I");
QVERIFY(invalidId == nullptr);
// check that all exceptions are already cleared
QVERIFY(!env.checkAndClearExceptions());
}
QTEST_MAIN(tst_QJniEnvironment)
#include "tst_qjnienvironment.moc"