Android系统从armeabi,armeabi-v7a,arm64-v8a加载本机库(so文件)的规则是什么?

时间:2016-03-08 06:42:26

标签: android android-ndk

假设我们在下面有一个jni文件夹结构。

armeabi
    a.so
    b.so
armeabi-v7a
    a.so

在基于ARMv7的设备上,我想加载b.so,但文件夹“armeabi-v7a”下没有b.so,因此系统会报告未找到的库错误或使用b.so在“armeabi”文件夹下?

更重要的是,系统在armeabiarmeabi-v7aarm64-v8ax86x86_64中查找so文件的顺序是什么?例如,在基于x86_64的设备上,系统首先在文件夹x86_64中查找so文件,但如果找不到,系统将继续在x86arm64-v8a中查找该文件,armeabi-v7aarmeabi按顺序排列?

2 个答案:

答案 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/3115956https://stackoverflow.com/a/28926267/3115956。假设您需要Android 4.0,这将减少文件大小而不会失去对目标用户群的任何重要部分的支持。如果您仍然定位旧版本,那么保留armeabi更为合理。