2017-08-02 2 views
1

NB Je suis pas un utilisateur QtCreator. Je construis des applications Android dans des scripts de construction avec qmake, make et androiddeployqt, et les déploie sur le périphérique avec l'installation adb. Je voudrais être capable de voir la sortie de qDebug, qInfo etc, et aussi n'importe quelle sortie qml conole.log et tout autre bavardage du moteur QML, dans la sortie abd logcat. Mais dans une version vanillée d'une application Qt pour Android, de tels messages semblent être blackholés (ou du moins je n'ai aucune idée de l'endroit où ils vont).Quel est le moyen le plus simple de voir la connexion à partir d'une application Qt sur Android dans la sortie adb logcat?

J'ai eu un certain succès par la combinaison de:

  • enregistrement des Rediriger stderr utilisant qInstallMessageHandler (comme le montre here).

  • Rediriger stderr vers la journalisation Android en utilisant le code here.

Mais tout cela semble un peu maladroit et trop compliqué. Sûrement il y a une façon meilleure et plus simple? (Par exemple, avec Qt sous Windows, vous pouvez simplement construire avec CONFIG += console pour obtenir une fenêtre de console avec la journalisation affichée, mais cette option est spécifique à Windows).

Versions Qt à partir de la version 5.7 d'intérêt. Googling ce problème de redirection de sortie donne beaucoup de mention de adb shell setprop log.redirect-stdio true, mais autant que je sache, il n'a aucun effet sur stout/stderr de Qt apps.

Répondre

0

En fait, en combinant les aspects des deux solutions liées à la question au moins réduit à une fonction:

const char*const applicationName="myapp"; 

#ifdef ANDROIDQUIRKS // Set in my myapp.pro file for android builds 
#include <android/log.h> 

void myMessageHandler(
    QtMsgType type, 
    const QMessageLogContext& context, 
    const QString& msg 
) { 
    QString report=msg; 
    if (context.file && !QString(context.file).isEmpty()) { 
    report+=" in file "; 
    report+=QString(context.file); 
    report+=" line "; 
    report+=QString::number(context.line); 
    } 
    if (context.function && !QString(context.function).isEmpty()) { 
    report+=+" function "; 
    report+=QString(context.function); 
    } 
    const char*const local=report.toLocal8Bit().constData(); 
    switch (type) { 
    case QtDebugMsg: 
    __android_log_write(ANDROID_LOG_DEBUG,applicationName,local); 
    break; 
    case QtInfoMsg: 
    __android_log_write(ANDROID_LOG_INFO,applicationName,local); 
    break; 
    case QtWarningMsg: 
    __android_log_write(ANDROID_LOG_WARN,applicationName,local); 
    break; 
    case QtCriticalMsg: 
    __android_log_write(ANDROID_LOG_ERROR,applicationName,local); 
    break; 
    case QtFatalMsg: 
    default: 
    __android_log_write(ANDROID_LOG_FATAL,applicationName,local); 
    abort();  
    } 
} 
#endif 

... 

int main(int argc,char* argv[]) { 

    QGuiApplication app(argc,argv); 
#ifdef ANDROIDQUIRKS 
    qInstallMessageHandler(myMessageHandler); 
#endif 
    app.setApplicationName(applicationName); 
    ... 

Cela fait bouger les choses comme qInfo() << messages de C++ etconsole.log messages de QML. Ce qu'il n'obtient pas, c'est une sortie stdout/stderr, mais je peux vivre avec ça pour un nouveau code qui peut utiliser Qt logging partout.

En logcat, le code QML Component.onCompleted: console.log("QML completed") résultats dans

08-02 12:27:53.378 1199 1220 D myapp : QML completed in file qrc:///main.qml line 7 function onCompleted 

et en C++ le code qInfo() << "QQuickViewer setup completed"; produit

08-02 12:27:53.562 1199 1220 I myapp : QQuickViewer setup completed 

Installation du gestionnaire de messages avant même QGuiApplication est instancié semble fonctionner aussi bien, mais il ne génère aucune sortie supplémentaire (je note Qt sur iOS crache toutes sortes de choses au démarrage de la console xcode par exemple un avertissement de performance liant à https://wiki.qt.io/V4 et se demandait si Android a fait la moi; mais s'il émet quelque chose, il doit l'être avant que mon gestionnaire ne soit installé).