假设我们在下面有一个jni文件夹结构。
armeabi
a.so
b.so
armeabi-v7a
a.so
在基于ARMv7的设备上,我想加载b.so,但文件夹“armeabi-v7a”下没有b.so,因此系统会报告未找到的库错误或使用b.so在“armeabi”文件夹下?
更重要的是,系统在armeabi
,armeabi-v7a
,arm64-v8a
,x86
,x86_64
中查找so文件的顺序是什么?例如,在基于x86_64的设备上,系统首先在文件夹x86_64
中查找so文件,但如果找不到,系统将继续在x86
,arm64-v8a
中查找该文件,armeabi-v7a
,armeabi
按顺序排列?
答案 0 :(得分:4)
你见过:http://developer.android.com/ndk/guides/abis.html#am
我相信它会回答你的问题:
Play商店和包管理器都希望找到NDK生成的 APK中文件路径上的库匹配以下模式:
/lib/<abi>/lib<name>.so
如果系统找不到所需的本机共享库 他们,它不能使用它们。在这种情况下,应用程序本身必须复制 库结束,然后执行dlopen()。
在页面的下方是这一点:
在安装时自动提取本机代码
安装应用程序时,程序包管理器服务会扫描APK,并查找表单的任何共享库:
lib/<primary-abi>/lib<name>.so
如果找不到任何内容,并且您已定义了辅助ABI,则该服务将扫描该表单的共享库:
lib/<secondary-abi>/lib<name>.so
当它找到它正在寻找的库时,包管理器将它们复制到应用程序的数据目录(data / data // lib /)下的/lib/lib.so。 如果根本没有共享对象文件,则应用程序构建并安装,但在运行时崩溃。
因此,如果您使用的是armeabi-v7a架构,则必须复制lib/armeabi/libb.so
文件并使用dlopen(),因为PackageManager不知道您的应用中需要加载什么但确实在lib/armeabi-v7a
目录中找到了一些东西。
答案 1 :(得分:4)
除了Morrison Chang的回答之外,人们总是可以考虑完全放弃armeabi
部分(所以你不需要lib的两个副本,我猜这个副本很大)。实际上,很少有现代设备(运行Android 4.0或更高版本)支持armeabi
但不支持armeabi-v7a
(自Android 4.4以来都没有)。有关此案例,请参阅https://stackoverflow.com/a/30924571/3115956,https://stackoverflow.com/a/28926267/3115956。假设您需要Android 4.0,这将减少文件大小而不会失去对目标用户群的任何重要部分的支持。如果您仍然定位旧版本,那么保留armeabi
更为合理。