QtJenny:生成 C++ 代理类以访问 Android API

演示 QtJenny 的使用。

概述

本演示展示了QtJenny的使用,并利用它生成 C++ 代理类,以便从 C++ 代码访问 Android API。生成的 C++ 类在演示中用于执行各种操作,如调节音量和亮度、激活和关闭唤醒锁、发送通知和触发振动。这些操作是 Qt 没有实现的 Android API 的一部分。

使用 QtJenny 生成 C++ 类,无需手动编写JNI代码。

工作原理

演示包含两部分,一个名为qtjenny_consumer 的 Qt 项目和一个名为qtjenny_generator 的 Android Studio 项目。qtjenny_consumer 包含应用程序 UI 和使用生成的 C++ 头文件编写的代码。qtjenny_generator 包含 QtJenny 的类注解和Gradle 配置。

要启动演示,需要运行qtjenny_consumer 项目。在CMake 配置qtjenny_consumer 期间,代码生成会通过调用执行qtjenny_generator 项目目录下的gradlew 任务自动触发。

if (ANDROID)
    if (CMAKE_HOST_SYSTEM_NAME STREQUAL "Windows")
        set (gradlew_cmd "gradlew.bat")
    else()
         set (gradlew_cmd "./gradlew")
    endif()
    set (gradlew_arg "--rerun-tasks")
    set (gradlew_task "kaptReleaseKotlin")
    execute_process(COMMAND ${gradlew_cmd} ${gradlew_arg} ${gradlew_task}
    WORKING_DIRECTORY "${PROJECT_SOURCE_DIR}/qtjenny_generator")
else()
    message(FATAL_ERROR "Example only works on Android")
endif()
生成 C++ 头文件

C++ 头文件的生成始于qtjenny_generator 的构建,它会触发注释处理器处理GenerateCppCode.kt 中的注释。

@NativeClass
@NativeProxy(allMethods = false, allFields = false)
@NativeProxyForClasses(namespace = "android::os", classes = [BatteryManager::class, VibratorManager::class, Vibrator::class, VibrationEffect::class, Context::class, PowerManager::class, PowerManager.WakeLock::class])
@NativeProxyForClasses(namespace = "android::view", classes = [Window::class, WindowManager.LayoutParams::class])
@NativeProxyForClasses(namespace = "android::media", classes = [AudioManager::class])
@NativeProxyForClasses(namespace = "android::drawable", classes = [android.R.drawable::class])
@NativeProxyForClasses(namespace = "android::app", classes = [Activity::class, Notification::class, Notification.Builder::class, NotificationChannel::class, NotificationManager::class])
@NativeProxyForClasses(namespace = "android::provider", classes = [Settings.Global::class, Settings.System::class, Settings::class])
@NativeProxyForClasses(namespace = "android::content", classes = [Intent::class])

注释处理器随后在qtjenny_output 目录中生成 C++ 头文件。这些 C++ 头文件包含访问本演示中使用的 Android 应用程序接口所需的 JNI 模板代码。

qtjenny_generator 中的应用程序级build.gradle 脚本指定了 QtJenny 实现的kapt参数。这些参数在 QtJenny 编译器中进行解析,并在生成过程中使用。

kapt {
    arguments {
        // pass arguments to jenny
        arg("jenny.outputDirectory", project.file("../../qtjenny_output"))
        arg("jenny.templateDirectory", project.file("../templates"))
        arg("jenny.headerOnlyProxy", "true")
        arg("jenny.useJniHelper", "false")
        arg("jenny.useTemplates", "true")
    }
}
Qt Quick 应用程序中使用生成的 C++ 头文件

qtjenny_consumer 是使用qtjenny_generator 生成的 C++ 头文件的Qt Quick 应用程序。我们将生成的头文件包含在backend.h 文件中,并在backend.cpp 中使用它们访问各种 Android API。

应用程序的用户界面由一个Main.qml 文件组成,其中包含以下控件和操作。

唤醒锁

您可以使用Switches 激活和停用全部或部分唤醒锁。选中后,它们会调用backend.cpp 中的一个函数,激活唤醒锁并设置唤醒锁状态文本。

if (checked) {
    myBackEnd.setFullWakeLock()
    if (partialWakeLock.checked)
        partialWakeLock.click()
    mainWindow.wakeLockStatus = "Full WakeLock active"

设置部分唤醒锁使用的是与PowerManager.WakeLock Android API 相连接的WakeLockProxy 类。设置完全唤醒锁则使用连接到Window Android API 的WindowProxy

震动

您可以使用backend.cpp 中的vibrate 函数触发振动,该函数使用VibrationEffectProxyVibratorManagerProxyVibratorProxy 类来执行振动。

通知

发送通知由backend.cpp 中的notify 函数处理,并使用NotificationManagerProxy 类。

createNotification 函数中初始化Backend 类时已创建了通知。

调整亮度

调整亮度在adjustBrightness 函数backend.cpp 中处理,并使用IntentProxy,SettingsProxy,SystemProxy,ContextProxy,LayoutParamsProxyWindowProxy 类。

调整音量

调节音量由backend.cpp 中的adjustVolume 函数处理,并使用GlobalProxyAudioManagerProxy 类。

示例项目 @ code.qt.io

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