QJniEnvironment Class
QJniEnvironment 类提供对 JNI 环境 (JNIEnv) 的访问。更多
Header: | #include <QJniEnvironment> |
CMake: | find_package(Qt6 REQUIRED COMPONENTS Core) target_link_libraries(mytarget PRIVATE Qt6::Core) |
qmake: | QT += core |
自 | Qt 6.1 |
公共类型
enum class | OutputMode { Silent, Verbose } |
公共函数
QJniEnvironment() | |
~QJniEnvironment() | |
bool | checkAndClearExceptions(QJniEnvironment::OutputMode outputMode = OutputMode::Verbose) |
jclass | findClass(const char *className) |
(since 6.4) jfieldID | findField(jclass clazz, const char *fieldName) |
(since 6.2) jfieldID | findField(jclass clazz, const char *fieldName, const char *signature) |
(since 6.4) jmethodID | findMethod(jclass clazz, const char *methodName) |
(since 6.2) jmethodID | findMethod(jclass clazz, const char *methodName, const char *signature) |
(since 6.4) jfieldID | findStaticField(jclass clazz, const char *fieldName) |
(since 6.2) jfieldID | findStaticField(jclass clazz, const char *fieldName, const char *signature) |
(since 6.4) jmethodID | findStaticMethod(jclass clazz, const char *methodName) |
(since 6.2) jmethodID | findStaticMethod(jclass clazz, const char *methodName, const char *signature) |
(since 6.2) bool | isValid() const |
JNIEnv * | jniEnv() const |
bool | registerNativeMethods(std::initializer_list<JNINativeMethod> methods) |
bool | registerNativeMethods(const char *className, std::initializer_list<JNINativeMethod> methods) |
bool | registerNativeMethods(jclass clazz, std::initializer_list<JNINativeMethod> methods) |
bool | registerNativeMethods(const char *className, const JNINativeMethod[] methods, int size) |
bool | registerNativeMethods(jclass clazz, const JNINativeMethod[] methods, int size) |
JNIEnv & | operator*() const |
JNIEnv * | operator->() const |
静态公共成员
bool | checkAndClearExceptions(JNIEnv *env, QJniEnvironment::OutputMode outputMode = OutputMode::Verbose) |
JNIEnv * | getJniEnv() |
JavaVM * | javaVM() |
详细说明
使用 JNI 时,JNIEnv类是指向函数表的指针,每个 JNI 函数都有一个成员函数,通过函数表间接传递。JNIEnv
提供了大部分 JNI 函数。每个 C++ 本地函数的第一个参数都是JNIEnv
。线程之间不能共享 JNI 环境。
由于JNIEnv
不会进行太多的错误检查(如异常检查和清除),因此 QJniEnvironment 可以让您轻松地进行错误检查。
有关 JNIEnv 的更多信息,请参阅Java:接口函数表。
注意: 本 API 是为 Android 平台设计和测试的。尚未针对其他平台进行测试。
成员类型文档
enum class QJniEnvironment::OutputMode
常数 | 值 | 说明 |
---|---|---|
QJniEnvironment::OutputMode::Silent | 0 | 静默清除异常 |
QJniEnvironment::OutputMode::Verbose | 1 | 将异常及其堆栈回溯作为错误信息打印到stderr 流。 |
成员函数文档
QJniEnvironment::QJniEnvironment()
构造一个新的 JNI 环境对象,并将当前线程连接到 Java VM。
[noexcept]
QJniEnvironment::~QJniEnvironment()
将当前线程从 Java VM 中分离,并销毁QJniEnvironment 对象。这将通过调用checkAndClearExceptions() 清除所有待处理异常。
bool QJniEnvironment::checkAndClearExceptions(QJniEnvironment::OutputMode outputMode = OutputMode::Verbose)
根据outputMode ,以静默或报告堆栈回溯的方式清除任何待处理异常。
与在内部处理异常的QJniObject 不同,如果直接通过JNIEnv
进行 JNI 调用,则需要在调用后使用此函数清除任何潜在异常。有关可能抛出异常的JNIEnv
调用的更多信息,请参阅JNI 函数。
当一个待处理异常被清除时,返回true
。
[static]
bool QJniEnvironment::checkAndClearExceptions(JNIEnv *env, QJniEnvironment::OutputMode outputMode = OutputMode::Verbose)
清除env 的任何待处理异常,根据outputMode ,可以是无声的,也可以是报告堆栈回溯的。这在已经有JNIEnv
指针的情况下非常有用,例如在本地函数实现中。
与在内部处理异常的QJniObject 不同,如果直接通过JNIEnv
进行 JNI 调用,则需要在调用后使用该函数清除任何潜在异常。有关可能抛出异常的JNIEnv
调用的更多信息,请参阅JNI 函数。
当一个待处理异常被清除时,返回true
。
jclass QJniEnvironment::findClass(const char *className)
使用所有可用的类加载器搜索className 。Android 上的 Qt 使用自定义类加载器加载所有 .jar 文件,必须使用它来查找该类加载器创建的任何类,因为在使用默认类加载器时,这些类是不可见的。
如果className 未找到,则返回类指针或 null。
该函数的一个用例是搜索一个类,以调用一个需要jclass
的 JNI 方法。当对同一个类对象进行多次 JNI 调用时,该函数会非常有用,这比在每次调用中使用类名要快一些。此外,在进行 JNI 调用之前,该调用会首先查找内部缓存的类,如果找到,则返回这样的类。下面的代码片段创建了一个类CustomClass
的实例,然后调用printFromJava()
方法:
QJniEnvironment env; jclass javaClass = env.findClass("org/qtproject/example/android/CustomClass"); QJniObject javaMessage = QJniObject::fromString("findClass example"); QJniObject::callStaticMethod<void>(javaClass, "printFromJava", "(Ljava/lang/String;)V", javaMessage.object<jstring>());
注: 该调用会从内部缓存的类中返回对类对象的全局引用。
[since 6.4]
template <typename T> jfieldID QJniEnvironment::findField(jclass clazz, const char *fieldName)
搜索一个类的成员字段clazz 。字段由其fieldName 指定。字段的签名由模板参数推断。
如果未找到字段,则返回字段 ID 或nullptr
。
此函数在 Qt 6.4 中引入。
[since 6.2]
jfieldID QJniEnvironment::findField(jclass clazz, const char *fieldName, const char *signature)
搜索一个类的成员字段clazz 。字段由fieldName 和signature 指定。
如果未找到字段,则返回字段 ID 或nullptr
。
此方法的一个用例是搜索类字段并缓存其 ID,以便以后用于获取/设置字段。
此函数在 Qt 6.2 中引入。
[since 6.4]
template <typename... Args> jmethodID QJniEnvironment::findMethod(jclass clazz, const char *methodName)
搜索类clazz 的实例方法。方法由其methodName 指定,签名由模板参数推断。
如果未找到方法,则返回方法 ID 或nullptr
。
此函数在 Qt 6.4 中引入。
[since 6.2]
jmethodID QJniEnvironment::findMethod(jclass clazz, const char *methodName, const char *signature)
搜索一个类的实例方法clazz 。方法由methodName 和signature 指定。
如果未找到方法,则返回方法 ID 或nullptr
。
此方法的一个用例是搜索类方法并缓存其 ID,以便以后调用方法时使用。
此函数在 Qt 6.2 中引入。
[since 6.4]
template <typename T> jfieldID QJniEnvironment::findStaticField(jclass clazz, const char *fieldName)
搜索一个类的静态字段clazz 。该字段由fieldName 指定。字段的签名由模板参数推断。
如果未找到字段,则返回字段 ID 或nullptr
。
此函数在 Qt 6.4 中引入。
[since 6.2]
jfieldID QJniEnvironment::findStaticField(jclass clazz, const char *fieldName, const char *signature)
搜索clazz 类的静态字段。字段由fieldName 和signature 指定。
如果未找到字段,则返回字段 ID 或nullptr
。
此方法的一个用例是搜索类字段并缓存其 ID,以便以后用于获取/设置字段。
此函数在 Qt 6.2 中引入。
[since 6.4]
template <typename... Args> jmethodID QJniEnvironment::findStaticMethod(jclass clazz, const char *methodName)
搜索类clazz 的实例方法。方法由其methodName 指定,签名由模板参数推断。
如果未找到方法,则返回方法 ID 或nullptr
。
QJniEnvironment env; jclass javaClass = env.findClass("org/qtproject/example/android/CustomClass"); jmethodID methodId = env.findStaticMethod<void, jstring>(javaClass, "staticJavaMethod"); QJniObject javaMessage = QJniObject::fromString("findStaticMethod example"); QJniObject::callStaticMethod<void>(javaClass, methodId, javaMessage.object<jstring>());
此函数在 Qt 6.4 中引入。
[since 6.2]
jmethodID QJniEnvironment::findStaticMethod(jclass clazz, const char *methodName, const char *signature)
搜索一个类的静态方法clazz 。方法由methodName 和signature 指定。
如果未找到方法,则返回方法 ID 或nullptr
。
此方法的一个用例是搜索类方法并缓存其 ID,以便以后调用方法时使用。
QJniEnvironment env; jclass javaClass = env.findClass("org/qtproject/example/android/CustomClass"); jmethodID methodId = env.findStaticMethod(javaClass, "staticJavaMethod", "(Ljava/lang/String;)V"); QJniObject javaMessage = QJniObject::fromString("findStaticMethod example"); QJniObject::callStaticMethod<void>(javaClass, methodId, javaMessage.object<jstring>());
此函数在 Qt 6.2 中引入。
[static]
JNIEnv *QJniEnvironment::getJniEnv()
返回当前线程的 JNIEnv 指针。
当前线程将连接到 Java VM。
[since 6.2]
bool QJniEnvironment::isValid() const
如果此实例持有有效的 JNIEnv 对象,则返回true
。
此函数在 Qt 6.2 中引入。
[static]
JavaVM *QJniEnvironment::javaVM()
返回当前进程的 Java VM 接口。虽然每个进程可以有多个 Java VM,但 Android 只允许一个。
JNIEnv *QJniEnvironment::jniEnv() const
返回 JNI 环境的JNIEnv
指针。
template <typename Class> bool QJniEnvironment::registerNativeMethods(std::initializer_list<JNINativeMethod> methods)
这是一个重载函数。
将methods 中的 Java 方法与Class
所代表的 Java 类注册,并返回注册是否成功。
Class
类型必须使用Q_DECLARE_JNI_CLASS 宏在QtJniTypes 命名空间内声明。作为自由 C 或 C++ 函数实现的函数必须使用Q_DECLARE_JNI_NATIVE_METHOD 宏之一声明,并使用Q_JNI_NATIVE_METHOD 宏传入注册。
// C++ side Q_DECLARE_JNI_CLASS(MyJavaType, "my/java/Type") static void nativeFunction(JNIEnv *env, jobject thiz, jlong id) { // ... } Q_DECLARE_JNI_NATIVE_METHOD(nativeFunction) Q_DECL_EXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *reserved) { QJniEnvironment env; env.registerNativeMethods<QtJniTypes::MyJavaType>({ Q_JNI_NATIVE_METHOD(nativeFunction) }); } // Java side public class MyJavaType { native public nativeFunction(long id); }
对于作为静态类成员函数实现的函数,可使用macros for scoped functions 代替。
class NativeHandler { // ... private: static void handleChange(JNIEnv*, jobject, jlong id); Q_DECLARE_JNI_NATIVE_METHOD_IN_CURRENT_SCOPE(handleChange) }; \dots QJniEnvironment env; env.registerNativeMethods<QtJniTypes::MyJavaType>({ Q_JNI_NATIVE_SCOPED_METHOD(handleChange, NativeHandler) });
bool QJniEnvironment::registerNativeMethods(const char *className, std::initializer_list<JNINativeMethod> methods)
这是一个重载函数。
为 Java 类className 注册methods 中的本地函数方法。如果注册成功,则返回true
,否则返回false
。
bool QJniEnvironment::registerNativeMethods(jclass clazz, std::initializer_list<JNINativeMethod> methods)
这是一个重载函数。
为 Java 类clazz 注册methods 中的本地函数方法。如果注册成功,则返回true
,否则返回false
。
bool QJniEnvironment::registerNativeMethods(const char *className, const JNINativeMethod[] methods, int size)
这是一个重载函数。
在大小为size 的数组methods 中注册 Java 方法,每个方法都可以调用类className 中的本地 C++ 函数。在尝试调用这些方法之前,必须先注册它们。
如果注册成功,则返回true
,否则返回false
。
方法数组中的每个元素包括
- Java 方法名称
- 方法签名
- 将执行的 C++ 函数
const JNINativeMethod methods[] = {{"callNativeOne", "(I)V", reinterpret_cast<void *>(fromJavaOne)}, {"callNativeTwo", "(I)V", reinterpret_cast<void *>(fromJavaTwo)}}; QJniEnvironment env; env.registerNativeMethods("org/qtproject/android/TestJavaClass", methods, 2);
bool QJniEnvironment::registerNativeMethods(jclass clazz, const JNINativeMethod[] methods, int size)
这是一个重载函数。
重载函数使用先前缓存的 jclass 实例clazz 。
JNINativeMethod methods[] {{"callNativeOne", "(I)V", reinterpret_cast<void *>(fromJavaOne)}, {"callNativeTwo", "(I)V", reinterpret_cast<void *>(fromJavaTwo)}}; QJniEnvironment env; jclass clazz = env.findClass("org/qtproject/android/TestJavaClass"); env.registerNativeMethods(clazz, methods, 2);
JNIEnv &QJniEnvironment::operator*() const
返回 JNI 环境的JNIEnv
对象。
JNIEnv *QJniEnvironment::operator->() const
提供对 JNI 环境JNIEnv
指针的访问。
© 2025 The Qt Company Ltd. Documentation contributions included herein are the copyrights of their respective owners. The documentation provided herein is licensed under the terms of the GNU Free Documentation License version 1.3 as published by the Free Software Foundation. Qt and respective logos are trademarks of The Qt Company Ltd. in Finland and/or other countries worldwide. All other trademarks are property of their respective owners.