本页内容

QJniEnvironment Class

QJniEnvironment 类提供了对 JNI 环境(JNIEnv)的访问。更多内容...

头文件: #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()
QStringList stackTrace(int exception)

详细说明

在使用 JNI 时,JNIEnv类是一个指向函数表的指针,并为每个 JNI 函数提供一个通过该表间接调用的成员函数。JNIEnv 提供了大部分 JNI 函数。每个 C++ 本机函数都会将一个JNIEnv 作为第一个参数接收。JNI 环境不能在线程之间共享。

由于JNIEnv 几乎不进行错误检查(例如异常检查和清除),QJniEnvironment 允许您轻松地执行这些操作。

有关 JNIEnv 的更多信息,请参阅《Java:接口函数表》。

注意:此 API 专为 Android 设计并经过测试。尚未在其他平台上进行测试。

成员类型文档

enum class QJniEnvironment::OutputMode

常数值描述
QJniEnvironment::OutputMode::Silent0异常会被静默清除
QJniEnvironment::OutputMode::Verbose1将异常及其堆栈回溯作为错误打印到stderr 流中。

成员函数文档

QJniEnvironment::QJniEnvironment()

创建一个新的 JNI Environment 对象,并将当前线程附加到 Java 虚拟机上。

[noexcept] QJniEnvironment::~QJniEnvironment()

将当前线程从 Java 虚拟机中断开,并销毁 `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 虚拟机(Java VM)关联。

[since 6.2] bool QJniEnvironment::isValid() const

如果该实例持有有效的 JNIEnv 对象,则返回true 。

该函数在 Qt 6.2 中引入。

[static] JavaVM *QJniEnvironment::javaVM()

返回当前进程的 Java 虚拟机接口。尽管一个进程中可能存在多个 Java 虚拟机,但 Android 只允许存在一个。

JNIEnv *QJniEnvironment::jniEnv() const

返回 JNI 环境的JNIEnv 指针。

template <typename Class> bool QJniEnvironment::registerNativeMethods(std::initializer_list<JNINativeMethod> methods)

将 Java 方法注册到methods 中,对应的 Java 类由Class 表示,并返回注册是否成功。

Class 类型必须在QtJniTypes 命名空间内使用Q_DECLARE_JNI_CLASS 宏进行声明。作为自由 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)

将数组methods 中大小为size 的Java方法进行注册,其中每个方法均可调用类className 中的本机C++函数。在尝试调用这些方法之前,必须先将其注册。

若注册成功,则返回true ;否则返回false 。

methods数组中的每个元素包含:

  • 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);

这是一个重载函数。

[static] QStringList QJniEnvironment::stackTrace(int exception)

返回导致抛出exception 异常的堆栈跟踪。

JNIEnv &QJniEnvironment::operator*() const

返回 JNI 环境的 `JNIEnv ` 对象。

JNIEnv *QJniEnvironment::operator->() const

提供对JNI环境中的JNIEnv 指针的访问。

© 2026 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.