QJniObject: add callStatic[Object]Method overloads for jmethodID

This patch extends the QJniObject::callStatic[Object]Method functions
with the overload which accepts a jmethodID parameter. This can be
convenient when the method id is already cached and you do not want
to query the method by its name and signature.

Task-number: QTBUG-92952
Change-Id: Ib0852a5a27da2a244ac63112784751ef9e32cfa5
Reviewed-by: Leena Miettinen <riitta-leena.miettinen@qt.io>
Reviewed-by: Assam Boudjelthia <assam.boudjelthia@qt.io>
bb10
Ivan Solovev 2021-04-27 17:23:41 +02:00
parent 34f72ca52e
commit d225c6afe7
3 changed files with 247 additions and 0 deletions

View File

@ -916,6 +916,25 @@ QJniObject QJniObject::callStaticObjectMethodV(jclass clazz,
\endcode
*/
/*!
\fn template <typename T> T QJniObject::callStaticMethod(jclass clazz, jmethodID methodId, ...)
Calls the static method identified by \a methodId from the class \a clazz
with any subsequent arguments. Useful when \a clazz and \a methodId are
already cached from previous operations.
\code
QJniEnvironment env;
jclass javaMathClass = env.findClass("java/lang/Math");
jmethodID methodId = env.findStaticMethod(javaMathClass, "max", "(II)I");
if (methodId != 0) {
jint a = 2;
jint b = 4;
jint max = QJniObject::callStaticMethod<jint>(javaMathClass, methodId, a, b);
}
\endcode
*/
/*!
\fn template <typename T> T QJniObject::callStaticMethod(jclass clazz, const char *methodName)
@ -1013,6 +1032,35 @@ QJniObject QJniObject::callStaticObjectMethod(jclass clazz, const char *methodNa
return QJniObject();
}
/*!
\fn QJniObject QJniObject::callStaticObjectMethod(jclass clazz, jmethodID methodId, ...)
Calls the static method identified by \a methodId from the class \a clazz
with any subsequent arguments. Useful when \a clazz and \a methodId are
already cached from previous operations.
\code
QJniEnvironment env;
jclass clazz = env.findClass("java/lang/String");
jmethodID methodId = env.findStaticMethod(clazz, "valueOf", "(I)Ljava/lang/String;");
if (methodId != 0)
QJniObject str = QJniObject::callStaticObjectMethod(clazz, methodId, 10);
\endcode
*/
QJniObject QJniObject::callStaticObjectMethod(jclass clazz, jmethodID methodId, ...)
{
QJniEnvironment env;
if (clazz && methodId) {
va_list args;
va_start(args, methodId);
QJniObject res = getCleanJniObject(env->CallStaticObjectMethodV(clazz, methodId, args));
va_end(args);
return res;
}
return QJniObject();
}
/*!
\fn QJniObject QJniObject::callObjectMethod(const char *methodName) const

View File

@ -219,6 +219,36 @@ public:
}
}
template <typename T>
static T callStaticMethod(jclass clazz, jmethodID methodId, ...)
{
assertJniPrimitiveType<T>();
QJniEnvironment env;
T res{};
if (clazz && methodId) {
va_list args;
va_start(args, methodId);
callStaticMethodForType<T>(env.jniEnv(), res, clazz, methodId, args);
va_end(args);
if (env.checkAndClearExceptions())
res = {};
}
return res;
}
template <>
void callStaticMethod<void>(jclass clazz, jmethodID methodId, ...)
{
QJniEnvironment env;
if (clazz && methodId) {
va_list args;
va_start(args, methodId);
env->CallStaticVoidMethodV(clazz, methodId, args);
va_end(args);
env.checkAndClearExceptions();
}
}
template <typename T> static T callStaticMethod(jclass clazz, const char *methodName)
{
assertJniPrimitiveType<T>();
@ -254,6 +284,8 @@ public:
static QJniObject callStaticObjectMethod(jclass clazz, const char *methodName,
const char *signature, ...);
static QJniObject callStaticObjectMethod(jclass clazz, jmethodID methodId, ...);
template <typename T> T getField(const char *fieldName) const
{
assertJniPrimitiveType<T>();

View File

@ -65,22 +65,31 @@ private slots:
void compareOperatorTests();
void callStaticObjectMethodClassName();
void callStaticObjectMethod();
void callStaticObjectMethodById();
void callStaticBooleanMethodClassName();
void callStaticBooleanMethod();
void callStaticBooleanMethodById();
void callStaticCharMethodClassName();
void callStaticCharMethod();
void callStaticCharMethodById();
void callStaticIntMethodClassName();
void callStaticIntMethod();
void callStaticIntMethodById();
void callStaticByteMethodClassName();
void callStaticByteMethod();
void callStaticByteMethodById();
void callStaticDoubleMethodClassName();
void callStaticDoubleMethod();
void callStaticDoubleMethodById();
void callStaticFloatMethodClassName();
void callStaticFloatMethod();
void callStaticFloatMethodById();
void callStaticLongMethodClassName();
void callStaticLongMethod();
void callStaticLongMethodById();
void callStaticShortMethodClassName();
void callStaticShortMethod();
void callStaticShortMethodById();
void getStaticObjectFieldClassName();
void getStaticObjectField();
void getStaticIntFieldClassName();
@ -270,6 +279,28 @@ void tst_QJniObject::callStaticObjectMethod()
QCOMPARE(returnedString, QString::fromLatin1("test format"));
}
void tst_QJniObject::callStaticObjectMethodById()
{
QJniEnvironment env;
jclass cls = env.findClass("java/lang/String");
QVERIFY(cls != 0);
jmethodID id = env.findStaticMethod(
cls, "format", "(Ljava/lang/String;[Ljava/lang/Object;)Ljava/lang/String;");
QVERIFY(id != 0);
QJniObject formatString = QJniObject::fromString(QLatin1String("test format"));
QVERIFY(formatString.isValid());
QJniObject returnValue = QJniObject::callStaticObjectMethod(
cls, id, formatString.object<jstring>(), jobjectArray(0));
QVERIFY(returnValue.isValid());
QString returnedString = returnValue.toString();
QCOMPARE(returnedString, QString::fromLatin1("test format"));
}
void tst_QJniObject::callStaticBooleanMethod()
{
QJniEnvironment env;
@ -299,6 +330,32 @@ void tst_QJniObject::callStaticBooleanMethod()
}
}
void tst_QJniObject::callStaticBooleanMethodById()
{
QJniEnvironment env;
jclass cls = env.findClass("java/lang/Boolean");
QVERIFY(cls != 0);
jmethodID id = env.findStaticMethod(cls, "parseBoolean", "(Ljava/lang/String;)Z");
QVERIFY(id != 0);
{
QJniObject parameter = QJniObject::fromString("true");
QVERIFY(parameter.isValid());
jboolean b = QJniObject::callStaticMethod<jboolean>(cls, id, parameter.object<jstring>());
QVERIFY(b);
}
{
QJniObject parameter = QJniObject::fromString("false");
QVERIFY(parameter.isValid());
jboolean b = QJniObject::callStaticMethod<jboolean>(cls, id, parameter.object<jstring>());
QVERIFY(!b);
}
}
void tst_QJniObject::callStaticBooleanMethodClassName()
{
{
@ -352,6 +409,22 @@ void tst_QJniObject::callStaticByteMethod()
QCOMPARE(returnValue, jbyte(number.toInt()));
}
void tst_QJniObject::callStaticByteMethodById()
{
QJniEnvironment env;
jclass cls = env.findClass("java/lang/Byte");
QVERIFY(cls != 0);
jmethodID id = env.findStaticMethod(cls, "parseByte", "(Ljava/lang/String;)B");
QVERIFY(id != 0);
QString number = QString::number(123);
QJniObject parameter = QJniObject::fromString(number);
jbyte returnValue = QJniObject::callStaticMethod<jbyte>(cls, id, parameter.object<jstring>());
QCOMPARE(returnValue, jbyte(number.toInt()));
}
void tst_QJniObject::callStaticIntMethodClassName()
{
QString number = QString::number(123);
@ -381,6 +454,22 @@ void tst_QJniObject::callStaticIntMethod()
QCOMPARE(returnValue, number.toInt());
}
void tst_QJniObject::callStaticIntMethodById()
{
QJniEnvironment env;
jclass cls = env.findClass("java/lang/Integer");
QVERIFY(cls != 0);
jmethodID id = env.findStaticMethod(cls, "parseInt", "(Ljava/lang/String;)I");
QVERIFY(id != 0);
QString number = QString::number(123);
QJniObject parameter = QJniObject::fromString(number);
jint returnValue = QJniObject::callStaticMethod<jint>(cls, id, parameter.object<jstring>());
QCOMPARE(returnValue, number.toInt());
}
void tst_QJniObject::callStaticCharMethodClassName()
{
jchar returnValue = QJniObject::callStaticMethod<jchar>("java/lang/Character",
@ -404,6 +493,19 @@ void tst_QJniObject::callStaticCharMethod()
QCOMPARE(returnValue, jchar('A'));
}
void tst_QJniObject::callStaticCharMethodById()
{
QJniEnvironment env;
jclass cls = env.findClass("java/lang/Character");
QVERIFY(cls != 0);
jmethodID id = env.findStaticMethod(cls, "toUpperCase", "(C)C");
QVERIFY(id != 0);
jchar returnValue = QJniObject::callStaticMethod<jchar>(cls, id, jchar('a'));
QCOMPARE(returnValue, jchar('A'));
}
void tst_QJniObject::callStaticDoubleMethodClassName ()
{
QString number = QString::number(123.45);
@ -433,6 +535,23 @@ void tst_QJniObject::callStaticDoubleMethod()
QCOMPARE(returnValue, number.toDouble());
}
void tst_QJniObject::callStaticDoubleMethodById()
{
QJniEnvironment env;
jclass cls = env.findClass("java/lang/Double");
QVERIFY(cls != 0);
jmethodID id = env.findStaticMethod(cls, "parseDouble", "(Ljava/lang/String;)D");
QVERIFY(id != 0);
QString number = QString::number(123.45);
QJniObject parameter = QJniObject::fromString(number);
jdouble returnValue =
QJniObject::callStaticMethod<jdouble>(cls, id, parameter.object<jstring>());
QCOMPARE(returnValue, number.toDouble());
}
void tst_QJniObject::callStaticFloatMethodClassName()
{
QString number = QString::number(123.45);
@ -462,6 +581,22 @@ void tst_QJniObject::callStaticFloatMethod()
QCOMPARE(returnValue, number.toFloat());
}
void tst_QJniObject::callStaticFloatMethodById()
{
QJniEnvironment env;
jclass cls = env.findClass("java/lang/Float");
QVERIFY(cls != 0);
jmethodID id = env.findStaticMethod(cls, "parseFloat", "(Ljava/lang/String;)F");
QVERIFY(id != 0);
QString number = QString::number(123.45);
QJniObject parameter = QJniObject::fromString(number);
jfloat returnValue = QJniObject::callStaticMethod<jfloat>(cls, id, parameter.object<jstring>());
QCOMPARE(returnValue, number.toFloat());
}
void tst_QJniObject::callStaticShortMethodClassName()
{
QString number = QString::number(123);
@ -491,6 +626,22 @@ void tst_QJniObject::callStaticShortMethod()
QCOMPARE(returnValue, number.toShort());
}
void tst_QJniObject::callStaticShortMethodById()
{
QJniEnvironment env;
jclass cls = env.findClass("java/lang/Short");
QVERIFY(cls != 0);
jmethodID id = env.findStaticMethod(cls, "parseShort", "(Ljava/lang/String;)S");
QVERIFY(id != 0);
QString number = QString::number(123);
QJniObject parameter = QJniObject::fromString(number);
jshort returnValue = QJniObject::callStaticMethod<jshort>(cls, id, parameter.object<jstring>());
QCOMPARE(returnValue, number.toShort());
}
void tst_QJniObject::callStaticLongMethodClassName()
{
QString number = QString::number(123);
@ -519,6 +670,22 @@ void tst_QJniObject::callStaticLongMethod()
QCOMPARE(returnValue, jlong(number.toLong()));
}
void tst_QJniObject::callStaticLongMethodById()
{
QJniEnvironment env;
jclass cls = env.findClass("java/lang/Long");
QVERIFY(cls != 0);
jmethodID id = env.findStaticMethod(cls, "parseLong", "(Ljava/lang/String;)J");
QVERIFY(id != 0);
QString number = QString::number(123);
QJniObject parameter = QJniObject::fromString(number);
jlong returnValue = QJniObject::callStaticMethod<jlong>(cls, id, parameter.object<jstring>());
QCOMPARE(returnValue, jlong(number.toLong()));
}
void tst_QJniObject::getStaticObjectFieldClassName()
{
{