自定义QML模块部署到Android:缺少QML依赖项

时间:2016-02-11 14:36:37

标签: android qt deployment qml

开发一个包含一些特殊类型的自定义QML模块(让我们称之为MyModule)。它在其他应用程序项目中用作预编译库(即源代码不可用,它通过导入MyModule 1.0使用,设置必要的导入路径等)。该模块包含基于C ++的QML类型以及QML文件,这些文件本身导入QtQuick模块,如QtQuick.Controls和QtQuick.Window。

当我尝试使用MyModule部署并执行使用MyModule开发的应用程序时,Android将无法通过androiddeployqt / qmlimportscanner获取MyModule的依赖关系,并将其包含在APK中,从而产生以下消息:module "QtQuick.Controls" is not installed

有没有办法让这些QML依赖项包含在APK中,而无需在应用程序源目录中创建包含所有导入的虚拟qml文件,因此可以通过qmlimportscanner获取它们?

2 个答案:

答案 0 :(得分:3)

您可以尝试将depends关键字添加到qmldir文件中:

  

声明此模块依赖于另一个模块。

     

示例:

     

depends MyOtherModule 1.0

     

仅在隐藏依赖项的情况下才需要此声明:例如,当一个模块的C ++代码用于加载QML(可能是有条件的),然后依赖于其他模块。在这种情况下,依赖声明是必要的,以包括应用程序包中的其他模块。

要获得一些灵感,请查看以下内容:

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

答案 1 :(得分:0)

您可以将模块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应用程序中.gitignore文件夹中的内容./lib/。 (当然,您也可以使用更复杂的方法,例如Git子模块。)

替代解决方案

这是我在网络上找到的替代解决方案的列表。它们可能不适用于我的情况或有一些不利之处,但可能对您的情况有用。

1。创建带有导入的虚拟QML文件

同样在问题中提到,这是the usual workaround

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

例如here中的一些详细信息:

我在与.pro文件相同的目录中创建了一个简单的.qml文件。然后,我仅添加了其他文件夹中所有.qml文件中使用的导入行。由于这会导致语法问题,因此我还在最后一个导入行之后添加了文本Page {}。

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

Page { }

请注意,.pro文件中未引用此文件,当然,它根本不是项目/应用程序的一部分。它仅出于qmlimportscanner包含正确模块的目的而存在。

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

Sine Qt 5.14,这是此问题的正式解决方案,其跟踪为QTBUG-55259。有关详细信息,请参见此处。现在,qmlimportscanner将把项目.qrc文件中列出的所有QML文件视为可用于导入语句。因此,如果您的项目在QML文件中说import MyModule.Something,那么它将起作用,因为现在可以解决该导入了。

但是,如果模块MyModule驻留在项目的源代码树之外,并且自身导入了QML模块ExternalModule,而您的Android应用程序未导入该模块,则该导入仍将失败。 (我希望我正确地指出了这一点,因为我自己没有进行测试。)

3。从项目源代码树中链接模块的目录

Somebody reported在2018年末,qmlimportscanner将在查找包含import语句的QML文件时遵循从项目的源树到外部树的符号链接。

我尝试了此操作,但无法确认该行为。

4。呼叫qmlimportscanner多路径

qmlimportscanner能够考虑多个根路径(在哪里扫描导入其他QML文件的QML文件)和导入路径(在哪里解析这些导入的文件),像这样:

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

但是,androiddeployqt当前未按照QTBUG-75187使用此功能。因此,无论如何您都只能使用适用于Android的替代构建系统。 ECM build system也会在内部调用androiddeployqt。也许qt-android-cmake会有所帮助。

5。从qmake / CMake调用qml_import_qml_plugins()

从Qt 5.14开始,您可以从qmake / CMake文件中调用qmlimportscanner。不过,它仅对静态Qt构建有用:

在配置时运行qmlimportscanner,以找到使用的静态QML插件并将其链接到给定的目标。

注意:与非静态Qt构建一起使用时,此功能不执行任何操作。

source

乍一看,似乎没有一种方法可以让它在多个位置查找QML依赖关系,因此与当前情况相比,它可能没有任何改善。但我尚未对此进行详细探讨。