Spec-Zone.ru › Qt

Класс QJniObject

Удобная оболочка вокруг Java Native Interface (JNI). Подробнее...

Заголовок: #include <QJniObject>
CMake: find_package(Qt6 COMPONENTS Core REQUIRED) target_link_libraries(mytarget PRIVATE Qt6::Core)
qmake: QT += core
С момента: Qt 6.1
  • Список всех членов, включая унаследованные

Открытые функции

QJniObject(jobject object)
QJniObject(jclass clazz, const char *signature, ...)
QJniObject(jclass clazz)
QJniObject(const char *className, const char *signature, ...)
QJniObject(const char *className)
QJniObject()
~QJniObject()
T callMethod(const char *methodName, const char *signature, ...) const
T callMethod(const char *methodName) const
QJniObject callObjectMethod(const char *methodName) const
QJniObject callObjectMethod(const char *methodName, const char *signature, ...) const
QByteArray className() const
T getField(const char *fieldName) const
QJniObject getObjectField(const char *fieldName) const
QJniObject getObjectField(const char *fieldName, const char *signature) const
bool isValid() const
jobject object() const
jclass objectClass() const
void setField(const char *fieldName, T value)
void setField(const char *fieldName, const char *signature, T value)
QString toString() const
QJniObject & operator=(T object)

Статические открытые члены

T callStaticMethod(const char *className, const char *methodName, const char *signature, ...)
T callStaticMethod(const char *className, const char *methodName)
T callStaticMethod(jclass clazz, const char *methodName, const char *signature, ...)
T callStaticMethod(jclass clazz, jmethodID methodId, ...)
T callStaticMethod(jclass clazz, const char *methodName)
QJniObject callStaticObjectMethod(const char *className, const char *methodName)
QJniObject callStaticObjectMethod(const char *className, const char *methodName, const char *signature, ...)
QJniObject callStaticObjectMethod(jclass clazz, const char *methodName)
QJniObject callStaticObjectMethod(jclass clazz, const char *methodName, const char *signature, ...)
QJniObject callStaticObjectMethod(jclass clazz, jmethodID methodId, ...)
QJniObject fromLocalRef(jobject localRef)
QJniObject fromString(const QString &string)
T getStaticField(const char *className, const char *fieldName)
T getStaticField(jclass clazz, const char *fieldName)
QJniObject getStaticObjectField(const char *className, const char *fieldName)
QJniObject getStaticObjectField(const char *className, const char *fieldName, const char *signature)
QJniObject getStaticObjectField(jclass clazz, const char *fieldName)
QJniObject getStaticObjectField(jclass clazz, const char *fieldName, const char *signature)
bool isClassAvailable(const char *className)
void setStaticField(const char *className, const char *fieldName, T value)
void setStaticField(const char *className, const char *fieldName, const char *signature, T value)
void setStaticField(jclass clazz, const char *fieldName, const char *signature, T value)
void setStaticField(jclass clazz, const char *fieldName, T value)

Связанные нечлены

bool operator!=(const QJniObject &o1, const QJniObject &o2)
bool operator==(const QJniObject &o1, const QJniObject &o2)

Подробное описание

Класс QJniObject оборачивает ссылку на объект Java, гарантируя, что он не будет собран сборщиком мусора, и предоставляя доступ к большинству вызовов методов JNIEnv (член, статический) и полям (сеттер, геттер). Он устраняет большое количество служебного кода, который обычно необходим при прямом доступе к JNI для каждой операции, включая обработку исключений.

Примечание: Этот API был разработан и протестирован для использования с Android. Он не был протестирован для других платформ.

Общие замечания

  • Имена классов должны быть полностью квалифицированными, например: "java/lang/String".
  • Подписи методов написаны как "(ArgumentsTypes)ReturnType", см. Типы JNI.
  • Все типы объектов возвращаются как QJniObject.

Подписи методов

Для функций без аргументов QJniObject предоставляет удобные функции, которые будут использовать правильную подпись на основе предоставленного шаблона типа. Например:

jint x = QJniObject::callMethod<jint>("getSize");
QJniObject::callMethod<void>("touch");

В других случаях вам необходимо указать подпись самостоятельно, и важно, чтобы подпись соответствовала вызываемой функции. Структура подписи "(ArgumentsTypes)ReturnType". Типы массивов в подписи должны иметь префикс [, а имена типов с полным квалификатором Object должны иметь префикс L и суффикс ;.

Следующий пример демонстрирует, как вызвать две разные статические функции:

// Java class
package org.qtproject.qt;
class TestClass
{
   static String fromNumber(int x) { ... }
   static String[] stringArray(String s1, String s2) { ... }
}

Подпись для первой функции "(I)Ljava/lang/String;":

// C++ code
QJniObject stringNumber = QJniObject::callStaticObjectMethod("org/qtproject/qt/TestClass",
                                                             "fromNumber"
                                                             "(I)Ljava/lang/String;",
                                                             10);

и подпись для второй функции "(Ljava/lang/String;Ljava/lang/String;)[Ljava/lang/String;":

// C++ code
QJniObject string1 = QJniObject::fromString("String1");
QJniObject string2 = QJniObject::fromString("String2");
QJniObject stringArray = QJniObject::callStaticObjectMethod("org/qtproject/qt/TestClass",
                                                            "stringArray"
                                                            "(Ljava/lang/String;Ljava/lang/String;)[Ljava/lang/String;"
                                                            string1.object<jstring>(),
                                                            string2.object<jstring>());

Обработка исключений Java

После вызова функций Java, которые могут генерировать исключения, важно проверить, обработать и очистить любое исключение перед продолжением. Все функции QJniObject обрабатывают исключения внутри, сообщая и очищая их, что избавляет код клиента от необходимости обработки исключений.

Примечание: Пользователь должен вручную обрабатывать исключения при прямом использовании вызовов JNI JNIEnv. Небезопасно выполнять другие вызовы JNI, когда исключения ожидаются. Более подробная информация см. в QJniEnvironment::checkAndClearExceptions().

Методы Java Native

Методы Java Native позволяют вызывать нативный код из Java. Это делается путем создания объявления функции в Java и добавления к ней префикса native. Прежде чем нативная функция сможет быть вызвана из Java, вам необходимо сопоставить нативную функцию Java с нативной функцией в вашем коде. Сопоставление функций может быть выполнено с помощью вызова QJniEnvironment::registerNativeMethods().

Следующий пример демонстрирует, как это можно сделать.

Реализация на Java:

class FooJavaClass
{
    public static void foo(int x)
    {
        if (x < 100)
            callNativeOne(x);
        else
            callNativeTwo(x);
    }

private static native void callNativeOne(int x);
private static native void callNativeTwo(int x);

}

Реализация на C++:

static void fromJavaOne(JNIEnv *env, jobject thiz, jint x)
{
    Q_UNUSED(env);
    Q_UNUSED(thiz);
    qDebug() << x << "< 100";
}

static void fromJavaTwo(JNIEnv *env, jobject thiz, jint x)
{
    Q_UNUSED(env);
    Q_UNUSED(thiz);
    qDebug() << x << ">= 100";
}

void foo()
{
    // register the native methods first, ideally it better be done with the app start
    const JNINativeMethod methods[] =
                {{"callNativeOne", "(I)V", reinterpret_cast<void *>(fromJavaOne)},
                 {"callNativeTwo", "(I)V", reinterpret_cast<void *>(fromJavaTwo)}};
    QJniEnvironment env;
    env.registerNativeMethods("my/java/project/FooJavaClass", methods, 2);

    // Call the java method which will calls back to the C++ functions
    QJniObject::callStaticMethod<void>("my/java/project/FooJavaClass", "foo", "(I)V", 10);  // Output: 10 < 100
    QJniObject::callStaticMethod<void>("my/java/project/FooJavaClass", "foo", "(I)V", 100); // Output: 100 >= 100
}

Жизненный цикл объекта Java

Большинство объектов, полученных из Java, будут локальными ссылками и останутся действительными до возвращения из нативного метода. После этого объект становится доступным для сборки мусора. Если ваш код создает много локальных ссылок в цикле, вы должны удалять их вручную с каждой итерацией, иначе у вас может закончится память. Более подробную информацию см. в Обзор проектирования JNI: глобальные и локальные ссылки. Локальные ссылки, созданные вне области нативного метода, должны быть удалены вручную, так как сборщик мусора не освободит их автоматически, поскольку мы используем AttachCurrentThread. Более подробную информацию см. в Советы по JNI: локальные и глобальные ссылки.

Если вы хотите сохранить объект Java живым, вам необходимо либо создать новую глобальную ссылку на объект и освободить ее, когда вы закончите, либо создать новый QJniObject и позволить ему управлять жизненным циклом объекта Java.

Примечание: QJniObject управляет только своими собственными ссылками. Если вы создаете QJniObject из глобальной или локальной ссылки, эта ссылка не будет освобождена QJniObject.

Типы JNI

Типы объектов

Тип Подпись
jobject Ljava/lang/Object;
jclass Ljava/lang/Class;
jstring Ljava/lang/String;
jthrowable Ljava/lang/Throwable;
jobjectArray [Ljava/lang/Object;
jarray [<type>
jbooleanArray [Z
jbyteArray [B
jcharArray [C
jshortArray [S
jintArray [I
jlongArray [J
jfloatArray [F
jdoubleArray [D

Примитивные типы

Тип Подпись
jboolean Z
jbyte B
jchar C
jshort S
jint I
jlong J
jfloat F
jdouble D

Другие

Тип Подпись
void V
Пользовательский тип L<полное_имя>;

Дополнительную информацию о JNI см. в Спецификации Java Native Interface.

См. также QJniEnvironment и object().

Документация по членам функций

QJniObject::QJniObject(jobject object)

Создает новый объект JNI вокруг объекта Java object.

Примечание: QJniObject будет содержать ссылку на объект Java object и освободит ее при уничтожении. Любые ссылки на объект Java object вне QJniObject должны управляться вызывающим объектом. В большинстве случаев вы не должны вызывать эту функцию с локальной ссылкой, если не планируете самостоятельно управлять локальной ссылкой. См. QJniObject::fromLocalRef() для преобразования локальной ссылки в QJniObject.

См. также fromLocalRef().

QJniObject::QJniObject(jclass clazz, const char *signature, ...)

Создает новый объект JNI из clazz, вызывая конструктор с signature, определяющим типы последующих аргументов.

QJniEnvironment env;
jclass myClazz = env.findClass("org/qtproject/qt/TestClass");
QJniObject(myClazz, "(I)V", 3);

QJniObject::QJniObject(jclass clazz)

Создает новый объект JNI, вызывая конструктор по умолчанию для clazz.

Примечание: QJniObject создаст новую ссылку на класс clazz и освободит ее при уничтожении. Ссылки на созданный вне QJniObject класс должны управляться вызывающим объектом.

QJniObject::QJniObject(const char *className, const char *signature, ...)

Создает новый объект JNI, вызывая конструктор className с signature, определяющим типы последующих аргументов.

QJniEnvironment env;
char* str = "Hello";
jstring myJStringArg = env->NewStringUTF(str);
QJniObject myNewJavaString("java/lang/String", "(Ljava/lang/String;)V", myJStringArg);

QJniObject::QJniObject(const char *className)

Создает новый объект JNI, вызывая конструктор по умолчанию для className.

QJniObject myJavaString("java/lang/String");

QJniObject::QJniObject()

Создает недействительный объект JNI.

См. также isValid().

QJniObject::~QJniObject()

Уничтожает объект JNI и освобождает все ссылки, удерживаемые объектом JNI.

template <typename T> T QJniObject::callMethod(const char *methodName, const char *signature, ...) const

Вызывает метод объекта methodName с signature, определяющим типы последующих аргументов.

QJniObject myJavaStrin("org/qtproject/qt/TestClass");
jint index = myJavaString.callMethod<jint>("indexOf", "(I)I", 0x0051);

template <typename T> T QJniObject::callMethod(const char *methodName) const

Вызывает метод methodName и возвращает значение.

QJniObject myJavaStrin("org/qtproject/qt/TestClass");
jint size = myJavaString.callMethod<jint>("length");

template <typename T> QJniObject QJniObject::callObjectMethod(const char *methodName) const

Вызывает метод объекта Java methodName и возвращает новый QJniObject для возвращаемого объекта Java.

QJniObject myJavaString = QJniObject::fromString("Hello, Java");
QJniObject myJavaString2 = myJavaString1.callObjectMethod<jstring>("toString");

QJniObject QJniObject::callObjectMethod(const char *methodName, const char *signature, ...) const

Вызывает метод объекта Java methodName с signature, определяющим типы последующих аргументов.

QJniObject myJavaString = QJniObject::fromString("Hello, Java");
QJniObject mySubstring = myJavaString.callObjectMethod("substring",
                                                       "(II)Ljava/lang/String;", 7, 11);

[static] template <typename T> T QJniObject::callStaticMethod(const char *className, const char *methodName, const char *signature, ...)

Вызывает статический метод methodName из класса className с signature, определяющим типы последующих аргументов.

jint a = 2;
jint b = 4;
jint max = QJniObject::callStaticMethod<jint>("java/lang/Math", "max", "(II)I", a, b);

[static] template <typename T> T QJniObject::callStaticMethod(const char *className, const char *methodName)

Вызывает статический метод methodName класса className и возвращает значение.

jint value = QJniObject::callStaticMethod<jint>("MyClass", "staticMethod");

[static] template <typename T> T QJniObject::callStaticMethod(jclass clazz, const char *methodName, const char *signature, ...)

Вызывает статический метод methodName из clazz с signature, определяющим типы последующих аргументов.

QJniEnvironment env;
jclass javaMathClass = env.findClass("java/lang/Math");
jint a = 2;
jint b = 4;
jint max = QJniObject::callStaticMethod<jint>(javaMathClass, "max", "(II)I", a, b);

[static] template <typename T> T QJniObject::callStaticMethod(jclass clazz, jmethodID methodId, ...)

Вызывает статический метод, идентифицируемый methodId, из класса clazz с последующими аргументами. Полезно, когда clazz и methodId уже кэшированы из предыдущих операций.

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);
}

[static] template <typename T> T QJniObject::callStaticMethod(jclass clazz, const char *methodName)

Вызывает статический метод methodName в clazz и возвращает значение.

QJniEnvironment env;
jclass javaMathClass = env.findClass("java/lang/Math");
jdouble randNr = QJniObject::callStaticMethod<jdouble>(javaMathClass, "random");

[static] template <typename T> QJniObject QJniObject::callStaticObjectMethod(const char *className, const char *methodName)

Вызывает статический метод с methodName в классе className.

QJniObject string = QJniObject::callStaticObjectMethod<jstring>("CustomClass", "getClassName");

[static] QJniObject QJniObject::callStaticObjectMethod(const char *className, const char *methodName, const char *signature, ...)

Вызывает статический метод methodName из класса className с signature, определяющим типы последующих аргументов.

QJniObject thread = QJniObject::callStaticObjectMethod("java/lang/Thread", "currentThread",
                                                       "()Ljava/lang/Thread;");
QJniObject string = QJniObject::callStaticObjectMethod("java/lang/String", "valueOf",
                                                       "(I)Ljava/lang/String;", 10);

[static] template <typename T> QJniObject QJniObject::callStaticObjectMethod(jclass clazz, const char *methodName)

Вызывает статический метод с methodName в clazz.

[static] QJniObject QJniObject::callStaticObjectMethod(jclass clazz, const char *methodName, const char *signature, ...)

Вызывает статический метод methodName из класса clazz с signature, определяющим типы последующих аргументов.

[static] QJniObject QJniObject::callStaticObjectMethod(jclass clazz, jmethodID methodId, ...)

Вызывает статический метод, идентифицируемый methodId, из класса clazz с последующими аргументами. Полезно, когда clazz и methodId уже кэшированы из предыдущих операций.

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);

[since 6.2] QByteArray QJniObject::className() const

Возвращает имя объекта класса, удерживаемого QJniObject, как %%%CODE_BLOCK_44%%.

Эта функция была добавлена в Qt 6.2.

[static] QJniObject QJniObject::fromLocalRef(jobject localRef)

Создает QJniObject из локальной JNI-ссылок localRef. Эта функция принимает на себя владение localRef и освобождает его перед возвратом.

Примечание: Используйте эту функцию только с локальной JNI-ссылкой. Например, большинство прямых вызовов JNI через среду JNI возвращают локальные ссылки на объект Java.

jobject localRef = env->GetObjectArrayElement(array, index);
QJniObject element = QJniObject::fromLocalRef(localRef);

[static] QJniObject QJniObject::fromString(const QString &string)

Создает строку Java из QString string и возвращает QJniObject, содержащий эту строку.

QString myQString = "QString";
QJniObject myJavaString = QJniObject::fromString(myQString);

См. также toString().

template <typename T> T QJniObject::getField(const char *fieldName) const

Извлекает значение поля fieldName.

QJniObject volumeControl("org/qtproject/qt/TestClass");
jint fieldValue = volumeControl.getField<jint>("FIELD_NAME");

template <typename T> QJniObject QJniObject::getObjectField(const char *fieldName) const

Извлекает объект JNI из поля fieldName.

QJniObject field = jniObject.getObjectField<jstring>("FIELD_NAME");

QJniObject QJniObject::getObjectField(const char *fieldName, const char *signature) const

Извлекает объект JNI из поля fieldName с signature.

Примечание: Эта функция может использоваться без шаблона типа.

QJniObject field = jniObject.getObjectField("FIELD_NAME", "Ljava/lang/String;");

[static] template <typename T> T QJniObject::getStaticField(const char *className, const char *fieldName)

Извлекает значение из статического поля fieldName класса className.

[static] template <typename T> T QJniObject::getStaticField(jclass clazz, const char *fieldName)

Извлекает значение из статического поля fieldName в clazz.

[static] template <typename T> QJniObject QJniObject::getStaticObjectField(const char *className, const char *fieldName)

Извлекает объект из поля fieldName в классе className.

QJniObject jobj = QJniObject::getStaticObjectField<jstring>("class/with/Fields", "FIELD_NAME");

[static] QJniObject QJniObject::getStaticObjectField(const char *className, const char *fieldName, const char *signature)

Извлекает объект JNI из поля fieldName с signature из класса className.

Примечание: Эта функция может использоваться без шаблона типа.

QJniObject jobj = QJniObject::getStaticObjectField("class/with/Fields", "FIELD_NAME",
                                                   "Ljava/lang/String;");

[static] template <typename T> QJniObject QJniObject::getStaticObjectField(jclass clazz, const char *fieldName)

Извлекает объект из поля fieldName в clazz.

QJniObject jobj = QJniObject::getStaticObjectField<jstring>(clazz, "FIELD_NAME");

[static] QJniObject QJniObject::getStaticObjectField(jclass clazz, const char *fieldName, const char *signature)

Извлекает объект JNI из поля fieldName с signature из класса clazz.

Примечание: Эта функция может использоваться без шаблона типа.

QJniObject jobj = QJniObject::getStaticObjectField(clazz, "FIELD_NAME", "Ljava/lang/String;");

[static] bool QJniObject::isClassAvailable(const char *className)

Возвращает true, если класс Java className доступен.

if (QJniObject::isClassAvailable("java/lang/String")) {
    // condition statement
}

bool QJniObject::isValid() const

Возвращает true, если этот экземпляр содержит действительный объект Java.

QJniObject qjniObject;                        // ==> isValid() == false
QJniObject qjniObject(0)                      // ==> isValid() == false
QJniObject qjniObject("could/not/find/Class") // ==> isValid() == false

jobject QJniObject::object() const

Возвращает объект, удерживаемый QJniObject, либо как jobject, либо как тип T. T может быть одним из типов объектов JNI.

QJniObject string = QJniObject::fromString("Hello, JNI");
jstring jstring = string.object<jstring>();

Примечание: Возвращаемый объект все еще поддерживается этим QJniObject. Чтобы сохранить объект дольше срока действия этого QJniObject, например, чтобы записать его для последующего использования, самый простой способ — сохранить его в другом QJniObject с соответствующим сроком действия. В качестве альтернативы, можно создать новую глобальную ссылку на объект и сохранить его, позаботившись об освобождении, когда он больше не нужен.

void functionScope()
{
    QString helloString("Hello");
    jstring myJString = 0;
    {
        QJniObject string = QJniObject::fromString(helloString);
        myJString = string.object<jstring>();
    }

   // Ops! myJString is no longer valid.
}

[since 6.2] jclass QJniObject::objectClass() const

Возвращает объект класса, удерживаемый QJniObject, как jclass.

Примечание: Возвращаемый объект все еще поддерживается этим QJniObject. Чтобы сохранить объект дольше срока действия этого QJniObject, например, чтобы записать его для последующего использования, самый простой способ — сохранить его в другом QJniObject с соответствующим сроком действия. В качестве альтернативы, можно создать новую глобальную ссылку на объект и сохранить его, позаботившись об освобождении, когда он больше не нужен.

Эта функция была добавлена в Qt 6.2.

template <typename T> void QJniObject::setField(const char *fieldName, T value)

Устанавливает значение fieldName на value.

QJniObject obj;
obj.setField<jint>("AN_INT_FIELD", 10);
jstring myString = ...;
obj.setField<jstring>("A_STRING_FIELD", myString);

template <typename T> void QJniObject::setField(const char *fieldName, const char *signature, T value)

Устанавливает значение fieldName со signature на value.

QJniObject stringArray = ...;
QJniObject obj = ...;
obj.setObjectField<jobjectArray>("KEY_VALUES", "([Ljava/lang/String;)V",
                           stringArray.object<jobjectArray>())

[static] template <typename T> void QJniObject::setStaticField(const char *className, const char *fieldName, T value)

Устанавливает статическое поле fieldName класса className на value.

[static] template <typename T> void QJniObject::setStaticField(const char *className, const char *fieldName, const char *signature, T value)

Устанавливает статическое поле fieldName класса className на value, используя установщик с signature.

[static] template <typename T> void QJniObject::setStaticField(jclass clazz, const char *fieldName, const char *signature, T value)

Устанавливает статическое поле fieldName класса clazz на value, используя установщик с signature.

[static] template <typename T> void QJniObject::setStaticField(jclass clazz, const char *fieldName, T value)

Устанавливает статическое поле fieldName класса clazz на value.

QString QJniObject::toString() const

Возвращает QString со строковым представлением объекта Java. Вызов этой функции для объекта Java String — удобный способ получить фактические данные строки.

QJniObject string = ...; //  "Hello Java"
QString qstring = string.toString(); // "Hello Java"

См. также fromString().

template <typename T> QJniObject &QJniObject::operator=(T object)

Заменяет текущий объект на object. Старый объект Java будет освобождён.

Связанные нечленные функции

bool operator!=(const QJniObject &o1, const QJniObject &o2)

Возвращает true, если o1 ссылается на другой объект, чем o2.

bool operator==(const QJniObject &o1, const QJniObject &o2)

Возвращает true, если оба объекта, o1 и o2, ссылаются на один и тот же объект Java или оба являются NULL. В противном случае возвращает false.

© The Qt Company Ltd
Licensed under the GNU Free Documentation License, Version 1.3.
https://doc.qt.io/qt-6.2/qjniobject.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API