Qt5 QGeoPositionInfoSource::createDefaultSource() 在 Android 5.0 上崩溃

Posted

技术标签:

【中文标题】Qt5 QGeoPositionInfoSource::createDefaultSource() 在 Android 5.0 上崩溃【英文标题】:Qt5 QGeoPositionInfoSource::createDefaultSource() crashes on Android 5.0 【发布时间】:2017-07-03 09:35:51 【问题描述】:

我正在为 android 开发一个 Qt5 应用程序(使用 CMake!),目前我正在尝试使用 Qt 的 QGeoPositionInfoSource 读取位置数据。 到目前为止,我所有的应用程序都运行良好,但是当我运行时

auto source = QGeoPositionInfoSource::createDefaultSource(this);

应用程序立即崩溃,logcat 给了我:

I/__log_qt(  422): (II) dpw_qt5:    <last output from my app>
F/libc    (  422): Fatal signal 11 (SIGSEGV), code 1, fault addr 0x0 in tid 797 (QtThread)
I/DEBUG   (  333): *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
I/DEBUG   (  333): Build fingerprint: 'samsung/trltexx/trlte:5.0.1/LRX22C/N910FXXU1BOE3:user/release-keys'
I/DEBUG   (  333): Revision: '12'
I/DEBUG   (  333): ABI: 'arm'
I/DEBUG   (  333): pid: 422, tid: 797, name: QtThread  >>> org.qtproject.DPW <<<
I/DEBUG   (  333): signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 0x0
I/DEBUG   (  333):     r0 00000000  r1 9d2bedf8  r2 00010006  r3 be7eb61d
I/DEBUG   (  333):     r4 9d2bedf4  r5 9d2bedf8  r6 00000000  r7 9cffa030
I/DEBUG   (  333):     r8 9d2bedf4  r9 afd04388  sl 00000001  fp 9d2bf8dc
I/DEBUG   (  333):     ip 9cff9e80  sp 9d2bedd0  lr 9cff49b7  pc 9cff612e  cpsr 60070030
I/DEBUG   (  333): 
I/DEBUG   (  333): backtrace:
I/DEBUG   (  333):     #00 pc 0000512e  /data/data/org.qtproject.DPW/qt-reserved-files/plugins/position/libqtposition_android.so
I/DEBUG   (  333):     #01 pc 000039b3  /data/data/org.qtproject.DPW/qt-reserved-files/plugins/position/libqtposition_android.so

我使用了最后三个 Android NDK 和从 5.6 到 5.9 的几个版本的 Qt - 结果都相同,所以我认为我系统性地做错了。

我的AndroidManifest.xml 包含以下几行:

<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />

您对我可以从哪里开始调查有什么想法吗?

更新:

我一直在追溯调用堆栈的最顶层:

I/DEBUG   (  333):     #00 pc 0000512e  /data/data/org.qtproject.DPW

我发现jnipositioning.cpp 中的以下行导致了崩溃:

if (javaVM->GetEnv((void**)&jniEnv, JNI_VERSION_1_6) < 0) 

所以新的问题是:什么会使javavm-&gt;GetEnv()(在jni.h 中声明)崩溃?

另一个更新:

jpo38 指出使用 qmake 构建会导致 Android 应用程序不会崩溃。我已经设置了一个 github project 来展示这种行为。

所以现在的问题是:使用 CMake 和 qmake 配置的应用程序之间有什么区别?

【问题讨论】:

您应该尝试报告 Qt 错误。 我做到了:bugreports.qt.io/browse/QTBUG-59010 好。希望您能尽快得到答复。我建议您在 Qt 错误报告中发布 MCVE。当您这样做时,他们会更快地发现问题。祝你好运。 您是否尝试注册消息处理程序(qInstallMessageHandler)并查看是否在系统崩溃之前收到消息? 您是否在您的.pro 文件中添加了QT += positioning?您是否创建了 QGuiApplication 对象的实例? 【参考方案1】:

这显然工作得很好:

TestGeo.pro:

QT += core gui
QT += positioning
QT += widgets

TARGET = TestGeo
TEMPLATE = app

SOURCES += main.cpp

CONFIG += mobility
MOBILITY = 

main.cpp:

#include <QMainWindow>
#include <QApplication>

#include <QGeoPositionInfoSource>
#include <QDebug>

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

    QApplication a(argc, argv);

    QMainWindow w;

    qDebug() << "Creating";
    auto source = QGeoPositionInfoSource::createDefaultSource(&a);
    if ( source )
        qDebug() << "Created";
    else
        qDebug() << "NULL";

    w.show();

    return a.exec();

没有崩溃的程序输出:

Creating
Created

请注意,我没有将AndroidManifest.xml 文件添加到项目中。它适用于启用或禁用“本地化”。

我正在使用Android-22 目标在Nexus 6 上部署Android 5.1 (armeabi-v7a)。使用Qt 5.6 (GCC 4.9)。使用 NDK r11b

你的设置一定有问题。

所以做这个设置,生成工作的apk。然后提取此工作 apk 和失败 apk 的内容。通过检查差异(丢失的库、文件、不同的清单......),您可以确定您的 CMake 构建和部署环境有什么问题,然后修复它(可能通过手动复制 CMake 项目中丢失的文件)!

在您的情况下,缺少对 Qt 定位库的引用。只需将它们正确添加到您的AndroidManifest.xml

<meta-data android:name="android.app.load_local_libs" android:value="plugins/platforms/android/libqtforandroid.so:plugins/position/libqtposition_android.so"/>
<meta-data android:name="android.app.load_local_jars" android:value="jar/QtAndroid.jar:jar/QtAndroidAccessibility.jar:jar/QtAndroid-bundled.jar:jar/QtAndroidAccessibility-bundled.jar:jar/QtPositioning.jar:jar/QtPositioning-bundled.jar"/>
<meta-data android:name="android.app.static_init_classes" android:value="org.qtproject.qt5.android.positioning.QtPositioning:org.qtproject.qt5.android.positioning.QtPositioning"/>

【讨论】:

我在 bugreport 中查看了他的示例。他使用 CMake 和 VS 来构建他的项目。 应该从一个可行的解决方案(QtCreator、简单的 .pro、基本程序)开始,然后跟踪一个更复杂的解决方案(VS、CMake...)的不同之处,看看是什么导致了崩溃。 ..也许VS没有正确部署程序 好吧 - 我使用的是 CMake 但不是 VS。我将采用 jpo 的方法 - 将 qmake 项目转换为 CMake 项目.. 我已经为此设置了一个 github 项目:github.com/frans-fuerst/ShowQt5Location-android-cmake-qmake.git 你能不能给我贴一条线,显示如何在命令行上配置一个qmake 项目,为 Qt5 和 NDK 提供位置?我环顾四周,但没有发现任何问题:) @frans:您不需要所有这些,只需在 QtCreator 中打开 .pro 文件即可。这么简单的项目不需要 CMake。

以上是关于Qt5 QGeoPositionInfoSource::createDefaultSource() 在 Android 5.0 上崩溃的主要内容,如果未能解决你的问题,请参考以下文章

由于找不到qt5webenginecore.dll无法继续执

警告:找不到库:Qt5WebKitd.dll、Qt5Cored.dll pyinstaller

QT基础QT5 常用模块介绍

Qt5.15.0 升级至 Qt5.15.9 遇到的一些错误

Qt5.8以上版本编译Oracle数据库的OCI驱动教程

如何在 Qt5 中使用 OpenCV