Spec-Zone.ru › Qt 6.1

Класс 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
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
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, 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 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 позволяют вызывать код native из Java, для этого создается объявление функции в Java и префикс native ключевое слово. Прежде чем функция native может быть вызвана из Java, необходимо сопоставить функцию native Java с функцией native в вашем коде. Сопоставление функций можно выполнить, вызвав 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
    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, будут локальными ссылками и останутся действительными только до тех пор, пока вы не вернетесь из метода native. После этого объект становится доступным для сборки мусора. Если ваш код создает много локальных ссылок в цикле, вы должны удалять их вручную на каждой итерации, иначе вы можете столкнуться с нехваткой памяти. Для получения дополнительной информации см. Обзор проектирования JNI: глобальные и локальные ссылки. Локальные ссылки, созданные вне области метода native, должны быть удалены вручную, так как сборщик мусора не освободит их автоматически, поскольку мы используем 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, const char *methodName)

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

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

[static] шаблон <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] шаблон <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::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().

шаблон <typename T> T QJniObject::getField(const char *fieldName) const

Возвращает значение поля fieldName.

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

шаблон <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] шаблон <typename T> T QJniObject::getStaticField(const char *className, const char *fieldName)

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

[static] шаблон <typename T> T QJniObject::getStaticField(jclass clazz, const char *fieldName)

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

[static] шаблон <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] шаблон <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.
}

шаблон <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);

шаблон <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] шаблон <typename T> void QJniObject::setStaticField(const char *className, const char *fieldName, T value)

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

[static] шаблон <typename T> void QJniObject::setStaticField(const char *className, const char *fieldName, const char *signature, T value)

Устанавливает статическое поле fieldName в классе className в value с использованием сеттера с signature.

[static] шаблон <typename T> void QJniObject::setStaticField(jclass clazz, const char *fieldName, const char *signature, T value)

Устанавливает статическое поле fieldName в классе clazz в value с использованием сеттера с signature.

[static] шаблон <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().

шаблон <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.1/qjniobject.html

Spec-Zone.ru

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