首页 > 解决方案 > 在 Qt for Android 中使用 .aar

问题描述

我正在尝试将 org.libsdl.app-debug.aar 库与 Qt (5.15.2) Android 项目一起使用。org.libsdl.app-debug.aar 库是我在 Andriod Studio 3.6.3 中根据项目源代码https://www.libsdl.org (SDL2-2.0.14.zip) 构建的。

Qt 项目是一个简单的测试应用程序,其中从 MainActivity 调用 SecondActivity。将来,我想使用 org.libsdl.app-debug.aar 库中的 SdlActivity 而不是 SecondActivity。

因此,无需将 .aar 库连接到 Qt 项目,一切都对我有用:

I art     : Late-enabling -Xcheck:jni
W ActivityThread: Application org.qtproject.example.activityhandler is waiting for the debugger on port 8100...
I System.out: Sending WAIT chunk
I art     : Debugger is active
I System.out: Debugger has connected
I System.out: waiting for debugger to settle...
I art     : Starting a blocking GC Instrumentation
I System.out: waiting for debugger to settle...
I System.out: waiting for debugger to settle...
I System.out: waiting for debugger to settle...
I System.out: waiting for debugger to settle...
I System.out: waiting for debugger to settle...
I System.out: waiting for debugger to settle...
I System.out: waiting for debugger to settle...
I System.out: debugger has settled (1399)
V Monotype: SetAppTypeFace- try to flip, app = org.qtproject.example.activityhandler
V Monotype:     Typeface getFontPathFlipFont - systemFont = default#default
V Monotype: SetAppTypeFace- try to flip, app = org.qtproject.example.activityhandler
V Monotype:     Typeface getFontPathFlipFont - systemFont = default#default
W System  : ClassLoader referenced unknown path:
V BoostFramework: mAcquireFunc method = public int com.qualcomm.qti.Performance.perfLockAcquire(int,int[])
V BoostFramework: mReleaseFunc method = public int com.qualcomm.qti.Performance.perfLockRelease()
V BoostFramework: mAcquireTouchFunc method = public int com.qualcomm.qti.Performance.perfLockAcquireTouch(android.view.MotionEvent,android.util.DisplayMetrics,int,int[])
V BoostFramework: mIOPStart method = public int com.qualcomm.qti.Performance.perfIOPrefetchStart(int,java.lang.String)
V BoostFramework: mIOPStop method = public int com.qualcomm.qti.Performance.perfIOPrefetchStop()
V BoostFramework: BoostFramework() : mPerf = com.qualcomm.qti.Performance@c2c2061
V BoostFramework: BoostFramework() : mPerf = com.qualcomm.qti.Performance@cad8786
I QtCore  : Start
I Qt      : qt started
I Timeline: Timeline: ActivityThread_LAUNCH_ACTIVITY 198ms id: ActivityRecord{f4c0985 token=android.os.BinderProxy@d8b027b {org.qtproject.example.activityhandler/org.qtproject.qt5.android.bindings.QtActivity}} time:33912090
I Adreno  : QUALCOMM build                   : 7d18700, I8ee426a9a2
I Adreno  : Build Date                       : 10/07/16
I Adreno  : OpenGL ES Shader Compiler Version: XE031.09.00.03
I Adreno  : Local Branch                     :
I Adreno  : Remote Branch                    : quic/LA.BR.1.3.6_rb1.6
I Adreno  : Remote Branch                    : NONE
I Adreno  : Reconstruct Branch               : NOTHING
I OpenGLRenderer: Initialized EGL, version 1.4
D OpenGLRenderer: Swap behavior 1
W Qt A11Y : Could not activate platform accessibility.
I Timeline: Timeline: Activity_idle id: android.os.BinderProxy@d8b027b time:33912233
I art     : Debugger is no longer active
I art     : Starting a blocking GC Instrumentation
Could not load shared library symbols for 167 libraries, e.g. /system/lib/libcutils.so.
Use the "info sharedlibrary" command to see the complete listing.
Do you need "set solib-search-path" or "set sysroot"?

但是,只要我将 org.libsdl.app-debug.aar 库放在 android/libs 文件夹中并使用它构建应用程序,应用程序就会在以分段错误启动时崩溃:

I art     : Late-enabling -Xcheck:jni
W ActivityThread: Application org.qtproject.example.activityhandler is waiting for the debugger on port 8100...
I System.out: Sending WAIT chunk
I art     : Debugger is active
I art     : Starting a blocking GC Instrumentation
I System.out: Debugger has connected
I System.out: waiting for debugger to settle...
I System.out: waiting for debugger to settle...
I System.out: waiting for debugger to settle...
I System.out: waiting for debugger to settle...
I System.out: waiting for debugger to settle...
I System.out: waiting for debugger to settle...
I System.out: waiting for debugger to settle...
I System.out: debugger has settled (1400)
V Monotype: SetAppTypeFace- try to flip, app = org.qtproject.example.activityhandler
V Monotype:     Typeface getFontPathFlipFont - systemFont = default#default
V Monotype: SetAppTypeFace- try to flip, app = org.qtproject.example.activityhandler
V Monotype:     Typeface getFontPathFlipFont - systemFont = default#default
W System  : ClassLoader referenced unknown path:
I Qt JAVA : Can't find '/data/app/org.qtproject.example.activityhandler-1/lib/arm64/libQt5Core_armeabi-v7a.so'
I Qt JAVA : Can't find '/data/app/org.qtproject.example.activityhandler-1/lib/arm64/libQt5AndroidExtras_armeabi-v7a.so'
I Qt JAVA : Can't find '/data/app/org.qtproject.example.activityhandler-1/lib/arm64/libQt5Gui_armeabi-v7a.so'
I Qt JAVA : Can't find '/data/app/org.qtproject.example.activityhandler-1/lib/arm64/libQt5Widgets_armeabi-v7a.so'
I Qt JAVA : Can't find '/data/app/org.qtproject.example.activityhandler-1/lib/arm64/libplugins_platforms_qtforandroid_armeabi-v7a.so'
W System.err: java.lang.NullPointerException: Attempt to invoke virtual method 'boolean android.os.BaseBundle.containsKey(java.lang.String)' on a null object reference
W System.err:   at org.qtproject.qt5.android.QtNative$4.run(QtNative.java:495)
W System.err:   at org.qtproject.qt5.android.QtThread$2.run(QtThread.java:87)
W System.err:   at org.qtproject.qt5.android.QtThread$1.run(QtThread.java:61)
W System.err:   at java.lang.Thread.run(Thread.java:761)
W System.err: java.lang.Exception:
W System.err:   at org.qtproject.qt5.android.bindings.QtLoader.loadApplication(QtLoader.java:268)
W System.err:   at org.qtproject.qt5.android.bindings.QtLoader.startApp(QtLoader.java:505)
W System.err:   at org.qtproject.qt5.android.bindings.QtActivityLoader.onCreate(QtActivityLoader.java:166)
W System.err:   at org.qtproject.qt5.android.bindings.QtActivity.onCreateHook(QtActivity.java:267)
W System.err:   at org.qtproject.qt5.android.bindings.QtActivity.onCreate(QtActivity.java:274)
W System.err:   at android.app.Activity.performCreate(Activity.java:6743)
W System.err:   at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1119)
W System.err:   at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2605)
W System.err:   at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2713)
W System.err:   at android.app.ActivityThread.-wrap12(ActivityThread.java)
W System.err:   at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1463)
W System.err:   at android.os.Handler.dispatchMessage(Handler.java:102)
W System.err:   at android.os.Looper.loop(Looper.java:159)
W System.err:   at android.app.ActivityThread.main(ActivityThread.java:6130)
W System.err:   at java.lang.reflect.Method.invoke(Native Method)
W System.err:   at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:865)
W System.err:   at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:755)
V BoostFramework: mAcquireFunc method = public int com.qualcomm.qti.Performance.perfLockAcquire(int,int[])
V BoostFramework: mReleaseFunc method = public int com.qualcomm.qti.Performance.perfLockRelease()
V BoostFramework: mAcquireTouchFunc method = public int com.qualcomm.qti.Performance.perfLockAcquireTouch(android.view.MotionEvent,android.util.DisplayMetrics,int,int[])
V BoostFramework: mIOPStart method = public int com.qualcomm.qti.Performance.perfIOPrefetchStart(int,java.lang.String)
V BoostFramework: mIOPStop method = public int com.qualcomm.qti.Performance.perfIOPrefetchStop()
V BoostFramework: BoostFramework() : mPerf = com.qualcomm.qti.Performance@489a71e
V BoostFramework: BoostFramework() : mPerf = com.qualcomm.qti.Performance@ebb7bff
V ScrollView: physical density factor: 1.0
I Timeline: Timeline: ActivityThread_LAUNCH_ACTIVITY 122ms id: ActivityRecord{d0621fc token=android.os.BinderProxy@7f9d95b {org.qtproject.example.activityhandler/org.qtproject.qt5.android.bindings.QtActivity}} time:51963450
I Adreno  : QUALCOMM build                   : 7d18700, I8ee426a9a2
I Adreno  : Build Date                       : 10/07/16
I Adreno  : OpenGL ES Shader Compiler Version: XE031.09.00.03
I Adreno  : Local Branch                     :
I Adreno  : Remote Branch                    : quic/LA.BR.1.3.6_rb1.6
I Adreno  : Remote Branch                    : NONE
I Adreno  : Reconstruct Branch               : NOTHING
I OpenGLRenderer: Initialized EGL, version 1.4
D OpenGLRenderer: Swap behavior 1
I Timeline: Timeline: Activity_idle id: android.os.BinderProxy@7f9d95b time:51963591
I art     : Debugger is no longer active
I art     : Starting a blocking GC Instrumentation

«org.qtproject.example.activityhandler» crashed.

在调试中,我什至没有进入 main() 函数的第一行。我无法弄清楚到底是什么问题。将 .aar 库添加到项目时究竟会发生什么?如果两个项目之间的唯一区别是 android/libs 文件夹中存在 org.libsdl.app-debug.aar 库,为什么带有 .aar 的应用程序会在 main() 函数的第一行之前崩溃建?在 C/C++ 中加载原生库时,会调用 JNI_OnLoad(),但是,首先它在 org.libsdl.app-debug.aar 项目中,其次,我不知道这种情况是否与 JNI_OnLoad 有关( )。

在 Android Studio 中将 org.libsdl.app-debug.aar 构建为 .apk 时,此应用程序可以成功运行。为了构建.aar,我将builg.gradle从“应用插件:'com.android.application'”切换到“应用插件:'com.android.library'”并获取包含“包 org.libsdl.app;":

def buildAsLibrary = project.hasProperty('BUILD_AS_LIBRARY');
if (buildAsApplication) {
    apply plugin: 'com.android.application'
}
else {
    apply plugin: 'com.android.library'
}

android {
    compileSdkVersion 29
    buildToolsVersion "29.0.3"
    defaultConfig {
        if (buildAsApplication) {
            applicationId "org.libsdl.app"
        }
        minSdkVersion 16
        targetSdkVersion 29
        versionCode 1
        versionName "1.0"
        externalNativeBuild {
            ndkBuild {
                arguments "APP_PLATFORM=android-16"
                abiFilters 'armeabi-v7a', 'arm64-v8a', 'x86', 'x86_64'
            }
            // cmake {
            //     arguments "-DANDROID_APP_PLATFORM=android-16", "-DANDROID_STL=c++_static"
            //     // abiFilters 'armeabi-v7a', 'arm64-v8a', 'x86', 'x86_64'
            //     abiFilters 'arm64-v8a'
            // }
        }
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
    if (!project.hasProperty('EXCLUDE_NATIVE_LIBS')) {
        sourceSets.main {
            jniLibs.srcDir 'libs'
        }
        externalNativeBuild {
            ndkBuild {
                path 'jni/Android.mk'
            }
            // cmake {
            //     path 'jni/CMakeLists.txt'
            // }
        }
       
    }
    lintOptions {
        abortOnError false
    }
    
    if (buildAsLibrary) {
        libraryVariants.all { variant ->
//            variant.outputs.each { output ->
//                def outputFile = output.outputFile
//                if (outputFile != null && outputFile.name.endsWith(".aar")) {
//                    def fileName = "org.libsdl.app.aar";
//                    output.outputFile = new File(outputFile.parent, fileName);
//                }
//            }
            variant.outputs.all {
                outputFileName = "org.libsdl.app-${variant.name}.aar"
            }
        }
    }
    ndkVersion '21.1.6352462'
}

dependencies {
    implementation fileTree(include: ['*.jar'], dir: 'libs')
}

在 Qt 项目中,我的 build.gradle 如下所示:

buildscript {
    repositories {
        google()
        jcenter()
    }

    dependencies {
        classpath 'com.android.tools.build:gradle:3.6.3'
    }
}

repositories {
    google()
    jcenter()
}

apply plugin: 'com.android.application'

dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar', '*.aar'])
}

android {
    /*******************************************************
     * The following variables:
     * - androidBuildToolsVersion,
     * - androidCompileSdkVersion
     * - qt5AndroidDir - holds the path to qt android files
     *                   needed to build any Qt application
     *                   on Android.
     *
     * are defined in gradle.properties file. This file is
     * updated by QtCreator and androiddeployqt tools.
     * Changing them manually might break the compilation!
     *******************************************************/

    compileSdkVersion androidCompileSdkVersion.toInteger()

    buildToolsVersion '28.0.3'

    sourceSets {
        main {
            manifest.srcFile 'AndroidManifest.xml'
            java.srcDirs = [qt5AndroidDir + '/src', 'src', 'java']
            aidl.srcDirs = [qt5AndroidDir + '/src', 'src', 'aidl']
            res.srcDirs = [qt5AndroidDir + '/res', 'res']
            resources.srcDirs = ['resources']
            renderscript.srcDirs = ['src']
            assets.srcDirs = ['assets']
            jniLibs.srcDirs = ['libs']
       }
    }

    tasks.withType(JavaCompile) {
        options.incremental = true
    }

    compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8
    }

    lintOptions {
        abortOnError false
    }

    // Do not compress Qt binary resources file
    aaptOptions {
        noCompress 'rcc'
    }

    defaultConfig {
        resConfig "en"
        minSdkVersion = qtMinSdkVersion
        targetSdkVersion = qtTargetSdkVersion
    }
}

Android 的 Qt 项目已上传到https://github.com/ElijaM/customactivity15-mainwindow-sdl。库 android/libs/org.libsdl.app-debug.aar。如果您使用它构建项目,则应用程序在启动时会崩溃。如果您只是从 android/libs 文件夹中删除它并再次构建项目,那么该应用程序将正常工作。

提前感谢您的任何帮助和想法。

标签: androidqtaar

解决方案


推荐阅读