在移动设备上部署 C++ QML 插件的正确方法是啥?

Posted

技术标签:

【中文标题】在移动设备上部署 C++ QML 插件的正确方法是啥?【英文标题】:What is the proper way of deploying C++ QML plugins on mobile device?在移动设备上部署 C++ QML 插件的正确方法是什么? 【发布时间】:2014-03-29 14:47:27 【问题描述】:

我一直在使用 Box2D QML 插件,并且看起来非常好。 但是,我想在 android (SGS2) 上部署我的示例应用程序,但我似乎无法让它工作。无论我尝试在 AVD 上还是在设备上运行它,它都不起作用。 androiddeployqt 成功完成,但随后我得到“无法启动'MyApp'”并且没有其他信息说明它为什么无法启动。我可以在 AVD 和设备上成功运行 qml 应用程序,但这与插件有关,我找不到任何参考来解决它。

我尝试以不同的方式设置 DEPLOYMENTFOLDERS,但如果我弄错了,那么整个事情都会失败。即使我没有收到错误,在这种情况下我认为我做对了,它仍然无法启动。

我一直在努力解决这个问题,但找不到任何有用的信息来解决它。 如果您知道任何使用 c++ 插件并且可以成功部署在 android 设备上的项目,那也很好。

我正在使用为 android 编译的 Qt 5.2.0 和 box2d 的 qt5 分支

【问题讨论】:

【参考方案1】:

当我们试图让我们的 QML 模块在 Android Qt 应用程序中工作时,我们遇到了“找不到模块”错误。在 Qt 5.3 中,我们只能通过将插件部署到官方 Qt QML 模块所在的 QT_INSTALL_QML 目录来识别我们的 QML 插件。在我们的例子中,这个目录是 /opt/Qt/5.3/android_armv7/qml。

插件端

我们的插件.pro 文件如下所示:

TEMPLATE = lib
TARGET = prova
QT += qml quick multimedia
CONFIG += qt plugin c++11 console
CONFIG -= android_install
TARGET = $$qtLibraryTarget($$TARGET)
uri = com.mycompany.qmlcomponents

# Input
SOURCES += \
    src1.cpp \
    src2.cpp

HEADERS += \
    src1.h \
    src2.h

##The below is generated automatically by Qt Creator when you create a new "Qt Quick 2 Extension Plugin" project for Android

#Copies the qmldir file to the build directory
!equals(_PRO_FILE_PWD_, $$OUT_PWD) 
    copy_qmldir.target = $$OUT_PWD/qmldir
    copy_qmldir.depends = $$_PRO_FILE_PWD_/qmldir
    copy_qmldir.commands = $(COPY_FILE) \"$$replace(copy_qmldir.depends, /, $$QMAKE_DIR_SEP)\" \"$$replace(copy_qmldir.target, /, $$QMAKE_DIR_SEP)\"
    QMAKE_EXTRA_TARGETS += copy_qmldir
    PRE_TARGETDEPS += $$copy_qmldir.target


#Copies the qmldir file and the built plugin .so to the QT_INSTALL_QML directory
qmldir.files = qmldir
unix 
    installPath = $$[QT_INSTALL_QML]/$$replace(uri, \\., /)
    qmldir.path = $$installPath
    target.path = $$installPath
    INSTALLS += target qmldir

我们的qmldir(在插件源码树根目录)文件是:

module com.mycompany.qmlcomponents
plugin prova

应用端

.pro 文件如下所示:

TEMPLATE = app

QT += qml quick widgets multimedia

CONFIG+= console
SOURCES += main.cpp

RESOURCES += qml.qrc

# Additional import path used to resolve QML modules in Qt Creator's code model
QML_IMPORT_PATH =
# Default rules for deployment.
include(deployment.pri)

contains(ANDROID_TARGET_ARCH,armeabi-v7a) 
    ANDROID_EXTRA_LIBS = \
        /opt/Qt/5.3/android_armv7/qml/com/mycompany/qmlcomponents/libprova.so

重要提示:您的 qml 插件使用的任何库也必须列在 ANDROID_EXTRA_LIBS 中才能捆绑到 apk 中。这也包括 Qt 组件,如果您不在应用程序中使用它们,在 QT+= 中列出它们是不够的。

我们实际上并不知道是否需要包含额外的 libprova.so。很可能不是。

main.cpp 看起来像:

#include <QApplication>
#include <QQmlApplicationEngine>
int main(int argc, char *argv[])
    QApplication app(argc, argv);
    QQmlApplicationEngine engine;
    engine.load(QUrl(QStringLiteral("qrc:///main.qml")));
    return app.exec();

main.qml 只包含如下插件:

import QtQuick 2.2
import QtQuick.Controls 1.1
import QtMultimedia 5.0

import com.mycompany.qmlcomponents 1.0

...

构建和部署

我们构建和部署插件的方式是到qmake(来自Qt的android-armv7工具链),然后是make install。它将 qmldir 文件和插件 .so 安装到 QT_INSTALL_QML 目录。

我们构建和部署使用插件的项目的方式是到qmake(同样来自Qt的android-armv7工具链),然后make install INSTALL_ROOT=.(安装到构建目录),然后运行androiddeployqt。最后一个命令使用 assets/ 中的 qmldirs 和 libs/ 中的库创建 Android 项目结构,并通过 ant 将整个东西捆绑在 apk 中。有关此过程的详细信息,请参阅http://qt-project.org/wiki/Android。

简而言之,我们只能通过将 QML 插件放在私有 Qt qml 目录中来让我们的 QML 插件在 Android 项目中被识别。我希望这会有所帮助。

【讨论】:

以上是关于在移动设备上部署 C++ QML 插件的正确方法是啥?的主要内容,如果未能解决你的问题,请参考以下文章

Qt/QML SwipeDelegate 在移动设备(Android、iOS)上无法正常工作

QML 创建 TreeView 动态模型的正确方法是啥?

QML插件扩展2(基于C++的插件扩展)

从 C++ 插件调用 QML 中的 JS 函数

在 Windows 上部署 Qt (C++/QML) 应用程序

捕获在不同线程中运行的方法异常的正确方法是啥?