JNI: Implement QJniObject::className to get the name of the class if not set

If we construct the QJniObject from a jobject, then we know the jclass,
but not the class's name. If className is called while the stored name
is empty, get the name of the jclass and updated the stored value.

Change-Id: Ic3332a6da2dac1eb6842f90da1b9264398a43155
Reviewed-by: Juha Vuolle <juha.vuolle@qt.io>
This commit is contained in:
Volker Hilsheimer 2023-09-24 04:58:19 +02:00
parent ca68fa01fe
commit 064b46779c
2 changed files with 37 additions and 2 deletions

View File

@ -809,6 +809,21 @@ jclass QJniObject::objectClass() const
*/
QByteArray QJniObject::className() const
{
if (d->m_className.isEmpty() && d->m_jclass && d->m_jobject) {
QJniEnvironment env;
if (env->PushLocalFrame(3) != JNI_OK) // JVM out of memory
return d->m_className;
jmethodID mid = env->GetMethodID(d->m_jclass, "getClass", "()Ljava/lang/Class;");
jobject classObject = env->CallObjectMethod(d->m_jobject, mid);
jclass classObjectClass = env->GetObjectClass(classObject);
mid = env->GetMethodID(classObjectClass, "getName", "()Ljava/lang/String;");
jstring stringObject = static_cast<jstring>(env->CallObjectMethod(classObject, mid));
const jsize length = env->GetStringUTFLength(stringObject);
const char* nameString = env->GetStringUTFChars(stringObject, NULL);
d->m_className = QByteArray::fromRawData(nameString, length).replace('.', '/');
env->ReleaseStringUTFChars(stringObject, nameString);
env->PopLocalFrame(nullptr);
}
return d->m_className;
}
@ -1311,8 +1326,11 @@ QJniObject QJniObject::getObjectField(const char *fieldName, const char *signatu
QJniObject QJniObject::fromString(const QString &string)
{
QJniEnvironment env;
return getCleanJniObject(env->NewString(reinterpret_cast<const jchar*>(string.constData()),
string.length()));
jstring stringRef = env->NewString(reinterpret_cast<const jchar*>(string.constData()),
string.length());
QJniObject stringObject = getCleanJniObject(stringRef);
stringObject.d->m_className = "java/lang/String";
return stringObject;
}
/*!

View File

@ -42,6 +42,7 @@ private slots:
void callObjectMethodTest();
void stringConvertionTest();
void compareOperatorTests();
void className();
void callStaticObjectMethodClassName();
void callStaticObjectMethod();
void callStaticObjectMethodById();
@ -300,6 +301,22 @@ void tst_QJniObject::compareOperatorTests()
QVERIFY(!invalidStringObject.isValid());
}
void tst_QJniObject::className()
{
const QString str("Hello!");
QJniObject jString = QJniObject::fromString(str);
{
QCOMPARE(jString.className(), "java/lang/String");
QCOMPARE(jString.toString(), str);
}
{
QJniObject strObject = QJniObject("java/lang/String", jString.object<jstring>());
QCOMPARE(strObject.className(), "java/lang/String");
QCOMPARE(strObject.toString(), str);
}
}
void tst_QJniObject::callStaticObjectMethodClassName()
{
QJniObject formatString = QJniObject::fromString(QLatin1String("test format"));