将自定义的QML模块部署到安卓设备:QML依赖项丢失。

3
我正在开发一个自定义的QML模块(我们称之为MyModule),其中包含一些特殊类型。它作为预编译库在其他应用程序项目中使用(即源代码对它们不可用,通过import MyModule 1.0导入并设置必要的导入路径等)。该模块包含基于C++的QML类型以及导入QtQuick模块(如QtQuick.Controls和QtQuick.Window)的QML文件。
当我尝试将使用MyModule开发的应用程序部署并在Android上执行时,androiddeployqt/qmlimportscanner没有捕获到MyModule的依赖项并将其包含在APK中,这会导致出现消息:“module "QtQuick.Controls" is not installed”。
有没有一种方法可以在不创建虚拟qml文件的情况下将这些QML依赖项包含在APK中,从而使其能够被qmlimportscanner捕获呢?
2个回答

4
您可以尝试将qmldir文件中的depends关键字添加进去:

声明此模块依赖于其他模块。

例如:

depends MyOtherModule 1.0

只有在依赖性被隐藏时,才需要进行此声明。例如,在一个模块的C++代码被用于加载QML(可能是有条件的)后,其依赖于其他模块。在这种情况下,depends声明对于将其他模块包含在应用程序包中是必要的。

您可以参考以下链接进行灵感启示:

http://code.qt.io/cgit/qt/qtquickcontrols2.git/tree/src/imports/controls/qmldir


1
您可以将模块MyModule放置在使用MyModule的Android应用程序的基目录下方的任何位置。例如,放置到文件夹./my-module./lib/my-module中。

工作原理

在运行qmake/CMake时,qmlimportscanner将在包含项目定义文件的文件夹上运行。对于基于qmake的项目,这是.pro文件,对于基于CMake的项目,这是CMakeLists.txt文件。它将查找此目录及其任何子目录中的所有*.qml文件,并将它们的QML依赖项包含到Android APK包中。至少这是qmlimportscanner的行为observed

您仍然可以在不同的Git存储库中管理您的QML模块MyModule和Android应用程序。只需确保在Android应用程序的./lib/文件夹中忽略.gitignore的内容即可。(当然,您也可以使用更复杂的方法,如Git子模块。)

 

备选方案

这里是我在网上找到的备选方案列表。它们可能对您有用,但要么在我的情况下不起作用,要么有一些缺点。

1. 使用导入创建虚拟QML文件

正如问题中提到的那样,这是通常的解决方法

解决方法是在项目目录中声明一个资源文件,其中包含必要的导入的虚拟qml文件。

这里了解更多详细信息和示例:

I created a simple .qml file in the same directory as the .pro file. Then I only added the import lines that are used within all my .qml files in other folders. Since this lead to a syntax complaint I also added the text Page {} after the last import line.

import QtQuick 2.9
import QtQuick.Layouts 1.3
import QtQuick.Controls 2.4
# [...]

Page { }

Note that this file is not referenced in the .pro file and is of course not part of the project / application at all. It only exists for the purpose that qmlimportscanner includes the correct modules.

2. 使用Qt 5.14并在.qrc文件中列出QML文件

自Qt 5.14起,这是官方解决该问题的方法,该问题被跟踪为QTBUG-55259。有关详细信息,请参见那里。现在,qmlimportscanner将考虑项目.qrc文件中列出的所有QML文件作为可用于导入语句的文件。因此,如果您的项目在QML文件中说import MyModule.Something,它将工作,因为现在可以解析该导入。

但是,如果您的模块MyModule位于项目源树之外,并且本身导入了未被Android应用程序导入的QML模块ExternalModule,则该导入仍将失败。(我希望我理解得对,因为我没有自己测试过。)

3. 在项目源树中的符号链接您的模块目录

有人在2018年底报告qmlimportscanner在查找包含import语句的QML文件时,会从项目源代码树到外部树跟随符号链接。

我尝试了这个功能,但无法证实其行为。

4. 使用多个路径调用qmlimportscanner

qmlimportscanner能够考虑多个根路径(扫描导入其他QML文件的QML文件的位置)和导入路径(解析这些导入的位置),如下所示:

qmlimportscanner -rootPath dir1 -rootPath dir2 -importPath dir3 -importPath dir4

然而,目前QTBUG-75187尚未使用androiddeployqt的此功能。因此,如果您在任何情况下都使用替代构建系统来构建Android应用程序,则可以使用它。ECM build system也会在内部调用androiddeployqt。也许qt-android-cmake可以提供帮助。
从Qt 5.14开始,您可以从qmake/CMake文件中调用qmlimportscanner。但这只适用于静态Qt构建。
在配置时运行 qmlimportscanner,查找使用的静态QML插件并将其链接到给定的目标。注意:当与非静态Qt构建一起使用时,此函数不起作用。(来源:source)
乍一看,似乎没有办法将多个位置交给它来查找QML依赖项,因此与当前情况相比可能不会有所改善。但我还没有详细探讨这个问题。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接