2013-08-19 11 views
9

Próbuję zaimportować wtyczkę TimeExample Qt Quick Extension z instalacji Androida Qt 5.1.0.Jak wdrożyć wtyczkę qt5 qml na Androida?

libqmlqtimeexampleplugin.so zbudowany jest z powodzeniem w build-plugins-Android_for_arm_GCC_4_6_Qt_5_1_0-Debug/imports

Potem stworzyłem prosty Qt Quick2 aplikacji (wbudowana Elements) z Qt Creator. Co powinienem dodać do pliku projektu aplikacji, aby uzyskać wtyczkę QML w wyjściowym pakiecie ".apk"?

Teraz mówi:

W/ilościowego (23528): Wartości: /qml/TimeExampleTest/main.qml 2(): Wartości: /qml/TimeExampleTest/main.qml: 2: 1 : moduł "TimeExample" nie jest zainstalowany

main.qml

import QtQuick 2.0 

import TimeExample 1.0 // import types from the plugin 

Rectangle { 
    width: 360 
    height: 360 
    Text { 
     text: qsTr("Hello World") 
     anchors.centerIn: parent 
    } 
    MouseArea { 
     anchors.fill: parent 
     onClicked: { 
      Qt.quit(); 
     } 
    } 

    Clock { // this class is defined in QML (imports/TimeExample/Clock.qml) 

     Time { // this class is defined in C++ (plugin.cpp) 
      id: time 
     } 

     hours: time.hour 
     minutes: time.minute 

    } 
} 

TimeExampleTest.pro

folder_01.source = qml/TimeExampleTest 

folder_01.target = qml 

folder_02.source = /home/artem/Projects/Veedo/Test/build-plugins-Android_for_arm_GCC_4_6_Qt_5_1_0-Debug/imports/TimeExample 

folder_02.target = imports 

DEPLOYMENTFOLDERS = folder_01 folder_02 

QML_IMPORT_PATH = /home/artem/Projects/Veedo/Test/build-plugins-Android_for_arm_GCC_4_6_Qt_5_1_0-Debug/imports/TimeExample 

SOURCES += main.cpp 

include(qtquick2applicationviewer/qtquick2applicationviewer.pri) 

qtcAddDeployment() 

OTHER_FILES += \ 
    android/src/org/kde/necessitas/ministro/IMinistro.aidl \ 
    android/src/org/kde/necessitas/ministro/IMinistroCallback.aidl \ 
    android/src/org/qtproject/qt5/android/bindings/QtActivity.java \ 
    android/src/org/qtproject/qt5/android/bindings/QtApplication.java \ 
    android/AndroidManifest.xml \ 
    android/version.xml \ 
    android/res/values-ja/strings.xml \ 
    android/res/values-rs/strings.xml \ 
    android/res/values-zh-rTW/strings.xml \ 
    android/res/values-fa/strings.xml \ 
    android/res/values-ru/strings.xml \ 
    android/res/values-fr/strings.xml \ 
    android/res/values-ro/strings.xml \ 
    android/res/values-el/strings.xml \ 
    android/res/values-ms/strings.xml \ 
    android/res/values-nb/strings.xml \ 
    android/res/values-et/strings.xml \ 
    android/res/values-pl/strings.xml \ 
    android/res/values-pt-rBR/strings.xml \ 
    android/res/values-es/strings.xml \ 
    android/res/values-id/strings.xml \ 
    android/res/values-de/strings.xml \ 
    android/res/values-it/strings.xml \ 
    android/res/values-zh-rCN/strings.xml \ 
    android/res/values/strings.xml \ 
    android/res/values/libs.xml \ 
    android/res/layout/splash.xml \ 
    android/res/values-nl/strings.xml 

Odpowiedz

6

Dzięki Qt 5.3 udało nam się uzyskać wtyczkę QML rozpoznawaną przez aplikację Qt Android tylko poprzez wdrożenie wtyczki do katalogu QT_INSTALL_QML, w którym znajdują się oficjalne moduły Qt QML. Ten katalog to /opt/Qt/5.3/android_armv7/qml w naszym przypadku.

Plugin Side

Nasz plik .pro dla wtyczki wygląda następująco:

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 
} 

Nasz plik

qmldir (w drzewie korzenia źródłowego wtyczki) to:

module com.mycompany.qmlcomponents 
plugin prova 

Application Strona

Plik .pro wygląda następująco:

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 
} 

My właściwie nie wiem, czy włączenie dodatkowego libprova.so jest konieczne. Najprawdopodobniej nie.

main.cpp wygląda następująco:

#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 tylko zawiera wtyczki jak:

import QtQuick 2.2 
import QtQuick.Controls 1.1 
import QtMultimedia 5.0 

import com.mycompany.qmlcomponents 1.0 

... 

Budowa i wdrożenie

nasz sposób zbudować i wdrożyć plugin jest qmake (z toolchainu android-armv7 z Qt), a następnie make install. Instaluje plik qmldir i wtyczkę .so do katalogu QT_INSTALL_QML.

Nasz sposób zbudować i wdrożyć projekt, który używa wtyczki jest qmake (ponownie, z android-ARMv7 toolchain Qt), następnie make install INSTALL_ROOT=. (instaluje zbudować katalog), a następnie uruchomić androiddeployqt.Ostatnie polecenie tworzy strukturę projektu Android z qmldirs w zasobach/i bibliotekach w libs/i pakuje całą rzecz w apk poprzez ant. Szczegółowe informacje na temat tej procedury można znaleźć na stronie http://qt-project.org/wiki/Android.

W skrócie, udało nam się uzyskać wtyczkę QML rozpoznaną tylko w projekcie Android, umieszczając ją w prywatnym katalogu qml Qt.

+0

Interesujące, ale iirc jest o wiele prostszy sposób, mogę wykopać/wypróbować kod, jeśli jesteś zainteresowany. – mlvljr

+0

Jestem zainteresowany @mlvljr! – user981733

+0

@ user981733 OK, pozwól mi zajrzeć do tego w kolejnych dniach, a następnie :) – mlvljr

0

Po przeczytaniu źródła Qt o QAbstractFileEngineHandler, znalazłem coś brzydkiego w Qt:

  1. Qt ma wdrożony jakiś mechanizm, aby zapewnić "SearchPath" (nie URL) jak "qrc:", „aktywów: ", gdzie jądro to QAbstractFileEngineHandler.

  2. QAbstractFileEngineHandler staje się już nie w Qt5 publicznego, to tylko dostarczyć streszczenie do QFile, QFileInfo, QDir, QIcon i rzeczy dostarczonych przez QFile, w tym QImage plus QAndroidAssetsFileEngineHandler, która specjalizuje się w przypadku aktywów z Androidem.

  3. Schemat SearchPath nie jest zgodny z QUrl, nawet jeśli wygląda tak podobnie, ponieważ wiesz, że QtQuick to setSource dla niektórych adresów URL, więc plik qml nie zostałby załadowany bezpośrednio przez prefiks "assets:".

  4. ten można znaleźć w dokumencie poniżej [static] void QDir::setSearchPaths(const QString &prefix, const QStringList &searchPaths) Qt:

    QDir::setSearchPaths("icons", QStringList(QDir::homePath() + "/images")); 
    QDir::setSearchPaths("docs", QStringList(":/embeddedDocuments")); 
    
    ...  
    QPixmap pixmap("icons:undo.png"); // will look for undo.png in QDir::homePath() + "/images"  
    QFile file("docs:design.odf"); // will look in the :/embeddedDocuments resource path 
    

    Znajdziesz ten fragment nie działa, ponieważ QPixmap nie załadować obraz z QAbstractFileEngineHandler, może to być nielegalni zmiany Qt. Z drugiej strony, jednostka testowa QtCore o SearchPath testowany tylko na QFile

Co więcej, void addResourceSearchPath(const QString &path) jest zastąpiony jednak setSearchPath jest wadliwy, czuję się bardzo mylić w tej sprawie. Może powinienem teraz rzucić okiem na QUrl :)

Powiązane problemy