Spec-Zone.ru › Qt 5.15

Класс QAndroidJniObject

Предоставляет API для вызова кода Java из C++. Подробнее...

Заголовок: #include <QAndroidJniObject>
qmake: QT += androidextras
С момента: Qt 5.2

Этот класс был представлен в Qt 5.2.

  • Список всех членов, включая наследуемые

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

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

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

T callStaticMethod(const char *className, const char *methodName)
T callStaticMethod(const char *className, const char *methodName, const char *signature, ...)
T callStaticMethod(jclass clazz, const char *methodName)
T callStaticMethod(jclass clazz, const char *methodName, const char *signature, ...)
QAndroidJniObject callStaticObjectMethod(const char *className, const char *methodName)
QAndroidJniObject callStaticObjectMethod(const char *className, const char *methodName, const char *signature, ...)
QAndroidJniObject callStaticObjectMethod(jclass clazz, const char *methodName)
QAndroidJniObject callStaticObjectMethod(jclass clazz, const char *methodName, const char *signature, ...)
QAndroidJniObject fromLocalRef(jobject localRef)
QAndroidJniObject fromString(const QString &string)
T getStaticField(const char *className, const char *fieldName)
T getStaticField(jclass clazz, const char *fieldName)
QAndroidJniObject getStaticObjectField(const char *className, const char *fieldName)
QAndroidJniObject getStaticObjectField(const char *className, const char *fieldName, const char *signature)
QAndroidJniObject getStaticObjectField(jclass clazz, const char *fieldName)
QAndroidJniObject getStaticObjectField(jclass clazz, const char *fieldName, const char *signature)
bool isClassAvailable(const char *className)
void setStaticField(const char *className, const char *fieldName, const char *signature, T value)
void setStaticField(const char *className, const char *fieldName, 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 QAndroidJniObject &o1, const QAndroidJniObject &o2)
bool operator==(const QAndroidJniObject &o1, const QAndroidJniObject &o2)

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

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

  • Имена классов должны содержать полное имя класса, например: "java/lang/String".
  • Подписи методов записываются как "(Аргументы)ТипВозвращаемогоЗначения"
  • Все типы объектов возвращаются как QAndroidJniObject.

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

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

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

В других случаях вам необходимо самостоятельно указать сигнатуру, и важно, чтобы она соответствовала функции, которую вы хотите вызвать. Структура сигнатуры — (A)R, где A — тип аргумента(ов), а R — тип возвращаемого значения. Типы массивов в сигнатуре должны иметь суффикс [, а полные имена типов должны иметь префикс L и суффикс ;.

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

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

Сигнатура первой функции — "(I)Ljava/lang/String;"

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

а сигнатура второй функции — "(Ljava/lang/String;Ljava/lang/String;)[Ljava/lang/String;"

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

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

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

Примечание: Вызов JNI небезопасен, если существуют ожидающие исключения.

void functionException()
{
    QAndroidJniObject myString = QAndroidJniObject::fromString("Hello");
    jchar c = myString.callMethod<jchar>("charAt", "(I)C", 1000);
    QAndroidJniEnvironment env;
    if (env->ExceptionCheck()) {
        // Handle exception here.
        env->ExceptionClear();
    }
}

Методы Java Native

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

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

Реализация 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 registerNativeMethods() {
    JNINativeMethod methods[] {{"callNativeOne", "(I)V", reinterpret_cast<void *>(fromJavaOne)},
                               {"callNativeTwo", "(I)V", reinterpret_cast<void *>(fromJavaTwo)}};

    QAndroidJniObject javaClass("my/java/project/FooJavaClass");
    QAndroidJniEnvironment env;
    jclass objectClass = env->GetObjectClass(javaClass.object<jobject>());
    env->RegisterNatives(objectClass,
                         methods,
                         sizeof(methods) / sizeof(methods[0]));
    env->DeleteLocalRef(objectClass);
}

void foo()
{
    QAndroidJniObject::callStaticMethod<void>("my/java/project/FooJavaClass", "foo", "(I)V", 10);  // Output: 10 < 100
    QAndroidJniObject::callStaticMethod<void>("my/java/project/FooJavaClass", "foo", "(I)V", 100); // Output: 100 >= 100
}

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

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

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

Типы 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 см.: http://docs.oracle.com/javase/7/docs/technotes/guides/jni/spec/jniTOC.html

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

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

QAndroidJniObject::QAndroidJniObject(jobject object)

Создаёт новый QAndroidJniObject для объекта Java object.

Примечание: QAndroidJniObject будет содержать ссылку на объект Java object и освободит её при уничтожении. Любые ссылки на объект Java object вне QAndroidJniObject должны управляться вызывающей стороной.

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

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

Создаёт новый QAndroidJniObject из clazz, вызывая конструктор с signature и аргументами.

jclass myClazz = ...;
QAndroidJniObject::QAndroidJniObject(myClazz, "(I)V", 3);

QAndroidJniObject::QAndroidJniObject(jclass clazz)

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

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

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

Создаёт новый QAndroidJniObject, вызывая конструктор className с signature и аргументами.

...
jstring myJStringArg = ...;
QAndroidJniObject myNewJavaString("java/lang/String", "(Ljava/lang/String;)V", myJStringArg);
...

QAndroidJniObject::QAndroidJniObject(const char *className)

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

...
QAndroidJniObject myJavaString("java/lang/String");
...

QAndroidJniObject::QAndroidJniObject()

Создаёт невалидный QAndroidJniObject.

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

QAndroidJniObject::~QAndroidJniObject()

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

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

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

QAndroidJniObject myJavaString = ...;
jint size = myJavaString.callMethod<jint>("length");

template <typename T> T QAndroidJniObject::callMethod(const char *methodName, const char *sig, ...) const

Вызывает метод methodName с сигнатурой sig и возвращает значение.

QAndroidJniObject myJavaString = ...;
jint index = myJavaString.callMethod<jint>("indexOf", "(I)I", 0x0051);

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

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

...
QAndroidJniObject myJavaString1 = ...;
QAndroidJniObject myJavaString2 = myJavaString1.callObjectMethod<jstring>("toString");
...

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

Вызывает метод объекта Java methodName с сигнатурой signature и аргументами.

QAndroidJniObject myJavaString; ==> "Hello, Java"
QAndroidJniObject mySubstring = myJavaString.callObjectMethod("substring", "(II)Ljava/lang/String;", 7, 10);

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

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

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

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

Вызывает статический метод methodName с signature для класса className с необязательными аргументами.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

...
QString myQString = "QString";
QAndroidJniObject myJavaString = QAndroidJniObject::fromString(myQString);
...

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

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

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

QAndroidJniObject volumeControl = ...;
jint fieldValue = volumeControl.getField<jint>("MAX_VOLUME");

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

Возвращает объект поля fieldName.

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

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

Возвращает объект из поля с signature и fieldName.

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

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

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

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

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

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

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

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

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

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

Возвращает объект из поля с signature и fieldName в классе className.

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

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

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

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

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

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

Возвращает объект из поля с signature и fieldName в clazz.

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

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

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

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

...
if (QAndroidJniObject::isClassAvailable("java/lang/String")) {
   ...
}
...

bool QAndroidJniObject::isValid() const

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

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

template <typename T> T QAndroidJniObject::object() const

Возвращает объект, содержащийся в QAndroidJniObject как тип T.

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

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

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

   // Ops! myJString is no longer valid.
}

Примечание: С Qt 5.3 эта функция может быть использована без шаблона типа, если возвращаемый тип — jobject.

jobject object = jniObject.object();

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

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

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

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

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

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

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

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

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

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

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

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

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

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

QString QAndroidJniObject::toString() const

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

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

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

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

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

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

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

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

bool operator==(const QAndroidJniObject &o1, const QAndroidJniObject &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-5.15/qandroidjniobject.html

Spec-Zone.ru

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