android - 在 adb logcat 输出中从 Android 上的 Qt 应用程序查看日志记录的最简单方法是什么?

标签 android qt adb logcat qdebug

注意我不是 QtCreator 用户。我使用 qmake、make 和 androiddeployqt 在构建脚本中构建 android 应用程序,并使用 adb install 将它们部署到设备。

我希望能够在 abd logcat 输出中看到 qDebug、qInfo 等的输出,以及任何 qml conole.log 输出和来自 QML 引擎的任何其他聊天记录。但是在 Android 版 Qt 应用程序的普通构建中,任何此类消息似乎都被黑洞了(或者至少我不知道它们要去哪里)。

我通过以下组合取得了一些成功:

  • 使用 qInstallMessageHandler 将日志记录重定向到 stderr (如图 here )。

  • 使用代码 here 将 stderr 重定向到 Android 日志记录. (更新:随后发现这种方法并不令人满意,因为它依赖于另一个线程监听管道,崩溃的应用程序可能会在崩溃前立即丢失日志记录)。

但这一切似乎有点笨拙和过于复杂。当然有更好更简单的方法吗? (例如,对于 Windows 上的 Qt,您可以简单地使用 CONFIG += console 进行构建以获得显示日志记录的控制台窗口,但该选项是特定于 Windows 的)。

感兴趣的 Qt 版本从 5.7 开始。

用谷歌搜索这个输出重定向问题会发现很多关于 adb shell setprop log.redirect-stdio true 的提及,但是据我所知它对 Qt 应用程序的粗壮/标准错误。

最佳答案

实际上,将问题中链接的两个解决方案的各个方面结合起来至少可以将其简化为一个功能:

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);
  ...

这会得到像 qInfo() << 这样的东西来自 C++ 的消息 console.log来自 QML 的消息。它没有得到的是 stdout/stderr 输出,但对于可以在整个过程中使用 Qt 日志记录的新代码,我可以接受它。

在 logcat 中,QML 代码 Component.onCompleted: console.log("QML completed")结果

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

在 C++ 中,代码 qInfo() << "QQuickViewer setup completed";产生

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

甚至在实例化 QGuiApplication 之前安装消息处理程序似乎同样有效,但它不会生成任何额外的输出(我注意到 iOS 上的 Qt 在启动时向 xcode 控制台喷出各种东西,例如性能警告链接到https://wiki.qt.io/V4 并想知道 Android 是否也这样做;但如果它发出任何东西,它必须在我的处理程序安装之前发出)。

关于android - 在 adb logcat 输出中从 Android 上的 Qt 应用程序查看日志记录的最简单方法是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45458064/

相关文章:

android - 从 Firebase 数据库中删除字段 (Android)

windows - Qt + 声子 : doesn't play on some computers

javascript - Qt WebView控件如何查看错误?

android - 无法让这个 adb shell am start 行工作

android - adb reboot 挂起 Genymotion

android - 多次运行 Espresso 测试

android - 更改一些代码后,我应该重新启动 Android 模拟器吗?

android - 如何确定 Widget 中的 TextView 宽度?

c++ - 在 TableView 中单击一行时显示在行中编辑字段

android - 如何重现android monkey crash?