我使用Android Studio 3.0.1和compileSdkVersion 26编写的Android应用程序。此应用程序依赖于用本机代码(c ++)编写的模块。模块中的本机代码取决于第三方共享库(.so)文件。在Cmake文件中,使用标准方法包含此第三方库,例如:
add_library( my-module-lib
SHARED
src/main/cpp/file1.cpp
src/main/cpp/file2.cpp )
add_library( libthird_party_library SHARED IMPORTED )
set_target_properties( libthird_party_library PROPERTIES IMPORTED_LOCATION ${pathToProject}/src/main/jniLibs/${ANDROID_ABI}/libthird_party_library.so)
target_link_libraries( my-module-lib libthird_party_library )
然后将我的模块作为依赖项添加到主应用程序,并使用以下命令加载本机代码:
System.loadLibrary("my-module-lib");
这一切都运行正常,但我需要更新第三方库。我认为这就像替换新的.so文件一样简单。但这导致了一个UnsatisfiedLinkError:
java.lang.UnsatisfiedLinkError: dlopen failed: library "libthird_party_library.so.2" not found
at java.lang.Runtime.loadLibrary0(Runtime.java:989)
at java.lang.System.loadLibrary(System.java:1567)
应该注意的是android现在搜索" .so.2"文件而不是" .so"文件。所以我认为由于某种原因旧的仍然包含在某个地方,并且由于名称冲突,新的一个被重命名为" *。2"。所以我试着摆脱它:
删除所有内容,即:
重建一切,即:
但这仍然导致相同的UnsatisfiedLinkError
将更新的库的名称更改为" libthird_party_library_NEW.so" 并更改cmake文件:
set_target_properties( libthird_party_library PROPERTIES IMPORTED_LOCATION ${pathToProject}/src/main/jniLibs/${ANDROID_ABI}/libthird_party_library_NEW.so)
相同错误
一个"解决方案"哪个工作正在重命名旧的" .so"使用重构>的文件将重命名为" libthird_party_library_OLD.so" ,然后使用标准名称" libthird_party_library.so"复制新的第三方库。 。但这当然不是一个非常好的解决方案,因为旧的不需要的库将包含在apk中。
答案 0 :(得分:0)
在android studio中链接版本化的共享库时,结果证明是个问题。与this question和here中描述的类似。
问题是" libthird_party_library.so "的内部版本号实际上是" libthird_party_library.so.2 "。这可以通过在.so文件上运行linux下的objdump来找到,即:
objdump -p libthird_party_library.so | grep so
输出:
libthird_party_library.so: file format elf64-little
NEEDED libm.so
NEEDED libc.so
NEEDED libdl.so
SONAME libthird_party_library.so.2
required from libdl.so:
required from libm.so:
required from libc.so:
由于android看到的文件名是" libthird_party_library.so "和android尝试加载" libthird_party_library.so.2 "它显然无法找到所需的库。
一个明显的解决方案是将文件名更改为" libthird_party_library.so.2 ",但这不起作用,因为android studio仅包含以结尾的库.so在apk(aaargh)。
解决方法是将内部版本号更改为" libthird_party_library_2.so ",将文件重命名为" libthird_party_library_2.so "并更改Cmake文件以反映此更改。
1)更改内部版本号可以在linux下使用:
完成rpl -R -e libthird_party_library.so.2 libthird_party_library_2.so libthird_party_library.so
第一个参数是内部版本号,第二个是我们需要将其更改为第三个参数,第三个参数是文件名。确定旧内部版本号的长度与新的一样!!
2)将文件名更改为" libthird_party_library_2.so "使用您最喜欢的工具
3)将CMake文件中的这一行改为
set_target_properties( libthird_party_library PROPERTIES IMPORTED_LOCATION ${pathToProject}/src/main/jniLibs/${ANDROID_ABI}/libthird_party_library_2.so)
希望这有帮助!