您可以将模块MyModule 放置在使用MyModule 的Android 应用程序的基目录下的任何位置。例如放入文件夹./my-module 或./lib/my-module。
工作原理
在运行 qmake / CMake 时,qmlimportscanner 将在包含项目定义文件的文件夹上运行。对于基于 qmake 的项目是 .pro 文件,对于基于 CMake 的项目是 CMakeLists.txt 文件。它将在此目录和任何子目录中查找所有 *.qml 文件,并将它们的 QML 依赖项包含到 Android APK 包中。至少这是observed 对qmlimportscanner 的行为。
您仍然可以在不同的 Git 存储库中管理您的 QML 模块 MyModule 和您的 Android 应用程序。只需确保 .gitignore Android 应用程序中 ./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 位于项目的源代码树之外,并且它本身导入了一个未由您的 Android 应用程序导入的 QML 模块 ExternalModule,则该导入仍然会失败。 (我希望我理解了这一点,因为我自己没有测试过。)
3。从项目源代码树符号链接你的模块目录
Somebody reported 在 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 可以提供帮助。
5。从 qmake / CMake 调用 qml_import_qml_plugins()
从 Qt 5.14 开始,您可以从您的 qmake / CMake 文件中调用 qmlimportscanner。不过,它只对静态 Qt 构建有用:
在配置时运行 qmlimportscanner 以查找使用的静态 QML 插件并将它们链接到给定目标。
注意:当与非静态 Qt 构建一起使用时,此函数不执行任何操作。
(source)
乍一看,似乎没有办法将多个位置交给它来查找 QML 依赖项,因此与当前情况相比,它可能不会有任何改进。但我还没有详细探讨。