提供 API 以调用 Java 代码从 C++。 更多...
头: | #include <QAndroidJniObject> |
qmake: | QT += androidextras |
Since: | Qt 5.2 |
QAndroidJniObject () | |
QAndroidJniObject (const char * className ) | |
QAndroidJniObject (const char * className , const char * signature , ... ) | |
QAndroidJniObject (jclass clazz ) | |
QAndroidJniObject (jclass clazz , const char * signature , ... ) | |
QAndroidJniObject (jobject object ) | |
~QAndroidJniObject () | |
T | callMethod (const char * methodName ) const |
T | callMethod (const char * methodName , const char * signature , ... ) 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 | 对象 () 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 ) |
提供 API 以调用 Java 代码从 C++。
For functions that take no arguments, QAndroidJniObject provides convenience functions that will use the correct signature based on the provided template type. For example:
jint x = QAndroidJniObject::callMethod<jint>("getSize"); QAndroidJniObject::callMethod<void>("touch");
In other cases you will need to supply the signature yourself, and it is important that the signature matches the function you want to call. The signature structure is (A)R ,其中 A is the type of the argument(s) and R is the return type. Array types in the signature must have the [ suffix and the fully-qualified type names must have the L prefix and ; suffix.
The example below demonstrates how to call two different static functions.
// Java class package org.qtproject.qt5; class TestClass { static String fromNumber(int x) { ... } static String[] stringArray(String s1, String s2) { ... } }
The signature for the first function is "(I)Ljava/lang/String;"
// C++ code QAndroidJniObject stringNumber = QAndroidJniObject::callStaticObjectMethod("org/qtproject/qt5/TestClass", "fromNumber" "(I)Ljava/lang/String;", 10);
and the signature for the second function is "(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>());
When calling Java functions that might throw an exception, it is important that you check, handle and clear out the exception before continuing.
注意: It is unsafe to make a JNI call when there are exceptions pending.
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 methods makes it possible to call native code from Java, this is done by creating a function declaration in Java and prefixing it with the native keyword. Before a native function can be called from Java, you need to map the Java native function to a native function in your code. Mapping functions can be done by calling the RegisterNatives() function through the JNI environment pointer .
The example below demonstrates how this could be done.
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 }
Most 对象 received from Java will be local references and will only stay valid in the scope you received them. After that, the object becomes eligible for garbage collection. If you want to keep a Java object alive you need to either create a new global reference to the object and release it when you are done, or construct a new QAndroidJniObject and let it manage the lifetime of the Java object.
注意: The QAndroidJniObject does only manage its own references, if you construct a QAndroidJniObject from a global or local reference that reference will not be released by the QAndroidJniObject .
类型 | 签名 |
---|---|
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 |
Custom type | L <fully-qualified-name> ; |
有关 JNI 的更多信息见: http://docs.oracle.com/javase/7/docs/technotes/guides/jni/spec/jniTOC.html
另请参阅 QAndroidJniEnvironment and 对象 ().
构造无效 QAndroidJniObject .
另请参阅 isValid ().
构造新的 QAndroidJniObject by calling the default constructor of className .
... QAndroidJniObject myJavaString("java/lang/String"); ...
构造新的 QAndroidJniObject by calling the constructor of className with signature and arguments.
... jstring myJStringArg = ...; QAndroidJniObject myNewJavaString("java/lang/String", "(Ljava/lang/String;)V", myJStringArg); ...
构造新的 QAndroidJniObject by calling the default constructor of clazz .
Note: The QAndroidJniObject will create a new reference to the class clazz and releases it again when it is destroyed. References to the class created outside the QAndroidJniObject needs to be managed by the caller.
构造新的 QAndroidJniObject from clazz by calling the constructor with signature and arguments.
jclass myClazz = ...; QAndroidJniObject::QAndroidJniObject(myClazz, "(I)V", 3);
构造新的 QAndroidJniObject around the Java object object .
Note: The QAndroidJniObject will hold a reference to the Java object object and release it when destroyed. Any references to the Java object object outside QAndroidJniObject needs to be managed by the caller.
另请参阅 fromLocalRef ().
销毁 QAndroidJniObject and releases any references held by the QAndroidJniObject .
Calls the method methodName and returns the value.
QAndroidJniObject myJavaString = ...; jint size = myJavaString.callMethod<jint>("length");
Calls the method methodName with signature and returns the value.
QAndroidJniObject myJavaString = ...; jint index = myJavaString.callMethod<jint>("indexOf", "(I)I", 0x0051);
Calls the Java objects method methodName 并返回新的 QAndroidJniObject for the returned Java object.
... QAndroidJniObject myJavaString1 = ...; QAndroidJniObject myJavaString2 = myJavaString1.callObjectMethod<jstring>("toString"); ...
Calls the Java object's method methodName with the signature signature and arguments
QAndroidJniObject myJavaString; ==> "Hello, Java" QAndroidJniObject mySubstring = myJavaString.callObjectMethod("substring", "(II)Ljava/lang/String;", 7, 10);
[static]
T
QAndroidJniObject::
callStaticMethod
(const
char
*
className
, const
char
*
methodName
)
调用静态方法 methodName on class className and returns the value.
jint value = QAndroidJniObject::callStaticMethod<jint>("MyClass", "staticMethod");
[static]
T
QAndroidJniObject::
callStaticMethod
(const
char
*
className
, const
char
*
methodName
, const
char
*
signature
,
...
)
调用静态方法采用 methodName with signature on class className with optional arguments.
... jint a = 2; jint b = 4; jint max = QAndroidJniObject::callStaticMethod<jint>("java/lang/Math", "max", "(II)I", a, b); ...
[static]
T
QAndroidJniObject::
callStaticMethod
(
jclass
clazz
, const
char
*
methodName
)
调用静态方法 methodName on clazz and returns the value.
... jclass javaMathClass = ...; // ("java/lang/Math") jdouble randNr = QAndroidJniObject::callStaticMethod<jdouble>(javaMathClass, "random"); ...
[static]
T
QAndroidJniObject::
callStaticMethod
(
jclass
clazz
, const
char
*
methodName
, const
char
*
signature
,
...
)
调用静态方法 methodName with signature on clazz and returns the value.
... jclass javaMathClass = ...; // ("java/lang/Math") jint a = 2; jint b = 4; jint max = QAndroidJniObject::callStaticMethod<jint>(javaMathClass, "max", "(II)I", a, b); ...
[static]
QAndroidJniObject
QAndroidJniObject::
callStaticObjectMethod
(const
char
*
className
, const
char
*
methodName
)
调用静态方法采用 methodName on the class className .
QAndroidJniObject string = QAndroidJniObject::callStaticObjectMethod<jstring>("CustomClass", "getClassName");
[static]
QAndroidJniObject
QAndroidJniObject::
callStaticObjectMethod
(const
char
*
className
, const
char
*
methodName
, const
char
*
signature
,
...
)
调用静态方法采用 methodName and signature on the class 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]
QAndroidJniObject
QAndroidJniObject::
callStaticObjectMethod
(
jclass
clazz
, const
char
*
methodName
)
调用静态方法采用 methodName on clazz .
[static]
QAndroidJniObject
QAndroidJniObject::
callStaticObjectMethod
(
jclass
clazz
, const
char
*
methodName
, const
char
*
signature
,
...
)
调用静态方法采用 methodName and signature on class clazz .
[static]
QAndroidJniObject
QAndroidJniObject::
fromLocalRef
(
jobject
localRef
)
创建 QAndroidJniObject 从本地 JNI 引用 localRef . This function takes ownership of localRef and frees it before returning.
注意: Only call this function with a local JNI reference. For example, most raw JNI calls, through the JNI environment, returns local references to a java object.
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 ().
Retrieves the value of the field fieldName .
QAndroidJniObject volumeControl = ...; jint fieldValue = volumeControl.getField<jint>("MAX_VOLUME");
Retrieves the object of field fieldName .
QAndroidJniObject field = jniObject.getObjectField<jstring>("FIELD_NAME");
Retrieves the object from the field with signature and fieldName .
注意: 由于 Qt 5.3 this function can be used without a template type.
QAndroidJniObject field = jniObject.getObjectField("FIELD_NAME", "Ljava/lang/String;");
[static]
T
QAndroidJniObject::
getStaticField
(const
char
*
className
, const
char
*
fieldName
)
Retrieves the value from the static field fieldName on the class className .
[static]
T
QAndroidJniObject::
getStaticField
(
jclass
clazz
, const
char
*
fieldName
)
Retrieves the value from the static field fieldName on clazz .
[static]
QAndroidJniObject
QAndroidJniObject::
getStaticObjectField
(const
char
*
className
, const
char
*
fieldName
)
Retrieves the object from the field fieldName on the class className .
QAndroidJniObject jobj = QAndroidJniObject::getStaticObjectField<jstring>("class/with/Fields", "FIELD_NAME");
[static]
QAndroidJniObject
QAndroidJniObject::
getStaticObjectField
(const
char
*
className
, const
char
*
fieldName
, const
char
*
signature
)
Retrieves the object from the field with signature and fieldName on class className .
注意: 由于 Qt 5.3 this function can be used without a template type.
QAndroidJniObject jobj = QAndroidJniObject::getStaticObjectField("class/with/Fields", "FIELD_NAME", "Ljava/lang/String;");
[static]
QAndroidJniObject
QAndroidJniObject::
getStaticObjectField
(
jclass
clazz
, const
char
*
fieldName
)
Retrieves the object from the field fieldName on clazz .
QAndroidJniObject jobj = QAndroidJniObject::getStaticObjectField<jstring>(clazz, "FIELD_NAME");
[static]
QAndroidJniObject
QAndroidJniObject::
getStaticObjectField
(
jclass
clazz
, const
char
*
fieldName
, const
char
*
signature
)
Retrieves the object from the field with signature and fieldName on clazz .
注意: 由于 Qt 5.3 this function can be used without a template type.
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")) { ... } ...
返回 true 若此实例保持有效 Java 对象。
... QAndroidJniObject qjniObject; ==> isValid() == false QAndroidJniObject qjniObject(0) ==> isValid() == false QAndroidJniObject qjniObject("could/not/find/Class") ==> isValid() == false ...
Returns the object held by the QAndroidJniObject as type T.
QAndroidJniObject string = QAndroidJniObject::fromString("Hello, JNI"); jstring jstring = string.object<jstring>();
注意: The returned object is still owned by the QAndroidJniObject . If you want to keep the object valid you should create a new QAndroidJniObject or make a new global reference to the object and free it yourself.
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
this function can be used without a template type, if the returned type is a
jobject
.
jobject object = jniObject.object();
设置值为 fieldName to value .
... QAndroidJniObject obj; obj.setField<jint>("AN_INT_FIELD", 10); jstring myString = ... obj.setField<jstring>("A_STRING_FIELD", myString); ...
设置值为 fieldName with signature to value .
QAndroidJniObject stringArray = ...; QAndroidJniObject obj = ...; obj.setField<jobjectArray>("KEY_VALUES", "([Ljava/lang/String;)V", stringArray.object<jobjectArray>())
[static]
void
QAndroidJniObject::
setStaticField
(const
char
*
className
, const
char
*
fieldName
, const
char
*
signature
,
T
value
)
设置静态字段采用 fieldName and signature to value on class className .
[static]
void
QAndroidJniObject::
setStaticField
(const
char
*
className
, const
char
*
fieldName
,
T
value
)
Sets the value of the static field fieldName in class className to value .
[static]
void
QAndroidJniObject::
setStaticField
(
jclass
clazz
, const
char
*
fieldName
, const
char
*
signature
,
T
value
)
设置静态字段采用 fieldName and signature to value on class clazz .
[static]
void
QAndroidJniObject::
setStaticField
(
jclass
clazz
, const
char
*
fieldName
,
T
value
)
设置静态字段 fieldName of the class clazz to value .
返回 QString with a string representation of the java object. Calling this function on a Java String object is a convenient way of getting the actual string data.
QAndroidJniObject string = ...; // "Hello Java" QString qstring = string.toString(); // "Hello Java"
另请参阅 fromString ().
替换当前对象以 object 。旧的 Java 对象将被释放。
返回 true 若 o1 holds a reference to a different object then o2 .
Returns true if both objects, o1 and o2 , are referencing the same Java object, or if both are NULL. In any other cases false will be returned.