Класс 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