android - 在 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 文件夹中删除它并再次构建项目,那么该应用程序将正常工作。
提前感谢您的任何帮助和想法。
解决方案
推荐阅读
- android - 通过 Kotlin DSL 从 local.properties 读取值
- google-search - 谷歌如何确定字典中单词的使用情况?
- ansible - 如何在 Ansible 中找到要使用的寄存器属性?
- python-3.x - 如何使用正则表达式从 Python 中的输入进行计算?
- html - 如何将 cookie 插件添加到静态 HTML 站点(归档的 wordpress 页面)?
- java - 如何在片段的活动中设置公共文本视图?
- javascript - 无法从 html 文件访问 script.js
- javascript - 在 react-player 中设置音频流
- apache - 当我想打开 html 文件时 apache2 不起作用
- javascript - 可重用的对象文字