本页内容

Qt for Android 的工作原理

如果您是希望了解 Qt 如何支持 Android 平台的高层概述的开发者,本页面正是为您准备的。

启动 Qt 应用程序

与原生 Android 应用类似,当应用启动并创建 Activity 时,Qt 主 Activity 的onCreate() 方法会在早期被调用。AndroidQt 平台抽象层(QPA)的大部分初始化工作都在此处进行。其中最重要的部分包括:

  • 加载 Qt 及主应用程序的库。
  • 初始化委托,负责初始化渲染表面和顶级布局,并注册各种监听器,如输入、显示、触摸处理程序等。

在加载 Qt 库时,QtCore 首次加载时会缓存 JavaVM。此操作在JNI_OnLoad()函数中完成,当使用System.load()调用加载库时,该函数会被同步调用。每个 Qt 模块都可能对此函数有自己的实现,以执行一些模块特有的初始化工作,例如注册本机 JNI 方法。

一旦所有 Qt 模块库均已加载,Qt 便会加载 Android QPA 插件和主应用程序库。当顶级QtLayout 布局完成内容加载后,系统会定位并调用 Qt 应用程序的 `main() ` 句柄。这将启动 C++ Qt 应用程序,并通常启动主事件循环。

Android QPA

Android QPA负责将 Android(Java/Kotlin)侧与原生 Qt(C++)侧进行绑定。 它处理 Qt 与 Android 之间双向的各种事件和信号传播。该职责涵盖信号处理、触摸事件、UI 元素以及渲染等。该层还负责应用程序启动时的初始化,以及应用程序退出或销毁时的清理工作。

线程

在 Qt for Android 应用中,Qt 通常涉及两个关键线程。第一个是 Qt 启动的 `QtThread `,第二个是 Android UI 线程。

QtThread

该线程由 Qt 应用程序在加载库等操作之前率先实现并启动。该线程被称为qtMainLoopThread 。以下所有操作均在此线程下执行:

  • Qt 库的加载。
  • 在JNI_OnLoad() 函数内执行的操作。
  • 启动原生应用程序。
  • main() 的执行。

Android UI 线程

与 Android 应用类似,影响 UI 的操作应在 UI 线程中运行。对于预期在 UI 中运行的任何内部调用,Qt 会在后台自动完成这一操作。 此外,Qt XML 还提供了一个 APIrunOnAndroidMainThread(),用于从 C++ 代码中在此线程下运行操作。通过此 API,Qt XML 会根据应用程序的状态进行管理:如果应用程序处于活动状态,则将调用直接发送到该线程;如果应用程序处于暂停或后台状态,则将调用放入队列。

架构

Qt for Android 架构概述

Qt 类

接下来的各节将详细介绍 Qt for Android 的各类类,以及它们在 Qt 应用程序中的功能和作用。

公共 Java 绑定

这些类是公共类,它们封装了面向用户的类(如Activity、Service和Application)的内部实现细节。Qt Android 应用默认使用这些类,并在 Android 清单文件中引用它们。构建系统和部署工具会自动将它们包含在构建中。

用户可以使用这些类来更改或扩展默认行为。例如,QtActivity 继承自Activity ,并实现了加载 Qt 库或处理 Android 与 Qt 之间事件及原生调用所需的逻辑。

如果需要使用 Qt 对各种事件以及 Qt 与 Android 之间调用的实现,通常需要继承 `QtActivity `。否则,继承 `Activity ` 即可满足需求。

要在onCreate() 中添加自定义逻辑,可采用以下方式:

public class MyActivity extends QtActivity
{
    @Override
    protected void onCreate(Bundle bundle)
    {
        // code before Qt is initialized
        super.onCreate(bundle);
        // code after Qt is initialized
    }
}

注意:您 必须编辑AndroidManifest.xml文件以使用自定义的Activity或绑定类,否则仍将使用默认的。

设置主题

在继承QtActivity 时,您可以使用setTheme() 设置特定的 Android 主题。但是,由于 Qt 默认会设置主题,因此该调用必须在调用父类的onCreate()之前进行,才能生效。例如,您可以使用:

@Override
protected void onCreate(Bundle bundle)
{
    setTheme(android.R.style.Theme_DeviceDefault_DayNight);
    super.onCreate(bundle);
}

默认情况下,对于 Android 10 及更高版本,Qt 会设置Theme_DeviceDefault_DayNight 样式;对于更早的版本,则设置Theme_Holo_Light 样式。

追加应用程序参数

若要追加一个额外的应用程序参数(即从 Java/Kotlin 传递给应用程序 `(main()) ` 函数的参数),可以在继承QtActivity 之后执行以下操作:

@Override
protected void onCreate(Bundle bundle)
{
    appendApplicationParameters("--flag value");
    super.onCreate(bundle);
}

这类似于直接使用 CMake 变量QT_ANDROID_APPLICATION_ARGUMENTS。无论采用哪种方法传递的参数,均可使用空格或制表符作为分隔符,而最终传递给应用程序的参数列表将通过QProcess::splitCommand 进行解析。

使用 QtLoader 加载 Qt 库

每个 Qt for Android 应用都需要确保在调用任何原生 Qt 或第三方库的功能之前,先加载这些库。 构建系统会在应用程序的libs.xml资源文件中保存各类 Qt 库依赖项、QPA 插件、主应用库以及任何第三方库的列表。一旦完成了下文各节中提到的所有先决步骤,即可通过System.load() 加载这些库。

类加载器

在加载 Qt 库或初始化委托之前,QtLoader 会尽早设置类加载器对象。这是因为QJniObject 会使用类加载器查找 Java 类,且通过QJniObject 进行任何 JNI 调用时都需要它。

设置环境变量和应用程序参数

在加载库之前,Qt 必须确保环境变量作为元数据传递到 Android 清单中以便进行设置。此步骤允许根据作为清单元数据设置的配置标志来初始化某些模块。其中部分元数据还会传播到应用程序参数列表中,并在应用程序启动时传递给应用程序。

setActivity()、setContext() 和 setService()

各种 Qt 模块可能需要从 Java 侧进行一些初始化工作,这需要Activity或Service 的上下文。这些模块随后会实现一个静态方法,该方法将Activity、Service 或 Context 作为参数:

void setActivity(Activity activity)
{
    m_activity = activity;
    // Other logic
}

随后,在加载原生共享库之前,QtLoader 会使用加载器的父级上下文来调用这些方法。

Qt for Android 如何处理 Android Activity 生命周期

Qt for Android 并未提供 API 来直接处理 Android 活动生命周期回调,例如 onCreate()、onStart()、onResume()、onPause()、onStop() 和 onDestroy()。相反,它会在后台为用户自动处理这些事务。相关行为将在以下各节中进行概述。

注意:这些 生命周期事件会被转换为QGuiApplication::applicationStateChanged 信号。

上下文处理

QAndroidApplication 可将 Android上下文作为QJniObject 提供,这是与 Android 系统交互所必需的。该上下文可以是 Activity,也可以是 Service。如果存在 Activity,则无论是否存在 Service,它都将是最近启动的 Activity;如果仅存在 Service,则它将是最近启动的 Service。

注意:Qt for Android 不支持多个 Activity。

回调

QtActivityBase类旨在将Activity各项功能的实现细节封装在Qt for Android包内,保持私有。该类作为Android生命周期与Qt框架之间的中介,将Android生命周期回调转换为Qt应用程序可响应的信号和操作。

onCreate()

当 Activity 被创建时,QtActivityBase 会初始化 Qt 环境。这包括加载 Qt 库、配置QJniObject 所使用的类加载器、解析应用的元数据,以及为 Qt 应用的执行做好准备。它确保处理了所有与该 Activity 相关的必要初始化工作。

onStart()

调用 Android 的 Activity.OnStart()。

onResume()

当 Activity 移至前台时,QtActivityBase 会恢复 Qt 应用程序的运行。这确保了已暂停的进程或操作得以继续,并且应用程序再次准备好响应用户交互。它将重新注册在 onPause() 中停止的显示管理器监听器。

onPause()

如果另一个 Activity 部分遮挡了当前 Activity,QtActivityBase 会暂停 Qt 应用程序。它将保存应用程序状态,或释放应用程序不在前台时不需要的资源。

onStop()

当该 Activity 不再可见时,QtActivityBase 会停止 Qt 应用程序,这涉及更全面的状态保存和资源释放,为应用程序可能被销毁做准备。

注意: 此时 QtThread 已被挂起。

onDestroy()

如果 Activity 已完成或正在被系统销毁,QtActivityBase 会清理与 Qt 应用程序相关的所有资源。它确保应用程序正确关闭,并执行所有必要的清理操作。

这种集成使开发人员能够专注于构建 Qt 应用程序,而无需担心 Android 生命周期的复杂性,因为 QtActivityBase 会在后台管理这些复杂情况。

启动画面管理

QAndroidApplication 可通过淡入淡出效果隐藏启动画面,该效果可与应用程序的启动序列同步,通常在 onCreate() 之后执行。

更多关于 Qt for Android 的信息

2021 年 Qt World Summit 的视频对 Qt for Android 进行了概述。

“一张链接到 YouTube 视频的议程图片”

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