在Android Studio(cmake)中使用预构建的共享库。
在Android Studio(cmake)中使用预构建的共享库。
我想在我的Android应用程序中使用一个C++共享库。
我尝试按照Google的NDK示例中的hello-libs
示例进行,但不知何故无法成功。
看起来,我的库没有打包到APK中。我找到的所有教程都使用*.mk
文件,但我想使用cmake
。
这是我的CMakeLists.txt文件:
# 设置构建本地库所需的CMake的最低版本。 cmake_minimum_required(VERSION 3.4.1) # 本地库 add_library(native-lib SHARED native-lib.cpp) set(IMPORT_DIR ${CMAKE_SOURCE_DIR}/../jniLibs) # 共享库 add_library(shared-lib SHARED IMPORTED) set_target_properties(shared-lib PROPERTIES IMPORTED_LOCATION ${IMPORT_DIR}/dynamic/lib/${ANDROID_ABI}/libLibrary.so) target_include_directories(native-lib PRIVATE ${IMPORT_DIR}/dynamic/include) # 链接库 target_link_libraries(native-lib android shared-lib log)
一旦我将shared-lib
与其他库链接起来,运行应用程序时就会出现以下错误:
E/art: dlopen("/data/app/my.package.name-1/lib/arm/libnative-lib.so", RTLD_LAZY) failed: dlopen failed: library "C:/projects/HelloLibs/app/src/main/cpp/../jniLibs/dynamic/lib/armeabi-v7a/libLibrary.so" not foun D/AndroidRuntime: Shutting down VM E/AndroidRuntime: FATAL EXCEPTION: main Process: my.package.name, PID: 29266 java.lang.UnsatisfiedLinkError: dlopen failed: library "C:/projects/HelloLibs/app/src/main/cpp/../jniLibs/dynamic/lib/armeabi-v7a/libLibrary.so" not found at java.lang.Runtime.loadLibrary(Runtime.java:371) at java.lang.System.loadLibrary(System.java:988) at my.package.name.MainActivity.(MainActivity.java:11) at java.lang.reflect.Constructor.newInstance(Native Method) at java.lang.Class.newInstance(Class.java:1690) at android.app.Instrumentation.newActivity(Instrumentation.java:1078) at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2543) at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2771) at android.app.ActivityThread.access$900(ActivityThread.java:177) at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1432) at android.os.Handler.dispatchMessage(Handler.java:102) at android.os.Looper.loop(Looper.java:135) at android.app.ActivityThread.main(ActivityThread.java:5912) at java.lang.reflect.Method.invoke(Native Method) at java.lang.reflect.Method.invoke(Method.java:372) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1405) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1200)
看起来设备上找不到该库。否则,库的路径看起来仍然是我本地机器上的路径。
问题的原因:在使用Android Studio进行开发时,如果想要将预构建的共享库打包到APK中,需要手动配置Gradle的sourceSets块,以包含.so文件的路径。这是因为Gradle默认不会自动包含预构建的共享库。
解决方法:在build.gradle文件中的android块中添加如下代码,将预构建共享库的路径包含进去。
android { ... sourceSets { main { jniLibs.srcDirs 'imported-lib/src/', 'more-imported-libs/src/' } } }
通过使用APK Analyzer(Build> Analyze APK...),可以验证Gradle将哪些库打包到APK中。
问题的出现原因:用户想在Android Studio中使用一个预先构建的共享库(.so文件),但不知道如何将其加载到项目中。
解决方法:将共享库文件放置在src/main/jniLibs
目录的相应目录中,然后可以直接加载库文件。即使Android Studio在本地方法声明中显示错误,但是应用程序仍然可以正常工作。
但是,用户想知道如何在native-lib-cpp
中使用这个库。这个共享库没有jni方法,用户希望将其包装到在Android Studio中编写的第二个库中。
解决方法:仍然可以从jniLibs文件夹中使用target_link_libraries
来链接它,只需要指定目录即可。但是用户想知道target_link_libraries
的确切参数。