x86/x86_64:这个架构是x86类型的,有32位和64位,占用的设备比例比较小
arm64-v8:这个架构是arm类型,主要用于Android5.0之后,cpu是64位的
这里可以看到,其中arm类型的是往下兼容策略,比如arm64-v8a肯定兼容armeabi/armeabi-v7a,
也就是说armeabi/armeabi-v7a架构的so文件可以用在arm64-v8a的设备中的,
八、Android插件中如何加载so文件
有时候我们在开发插件的时候,可能会调用so文件,一般来说有两种方案:
一种是在加载插件的时候,先把插件中的so文件释放到本地目录,然后在把目录设置到DexClassLoader类加载器的nativeLib中。
一种在插件初始化的时候,释放插件中的so文件到本地目录,然后使用System.load方法去全路径加载so文件
这两种方式的区别在于,第一种方式的代码逻辑放在了宿主工程中,同时so文件可以放在插件的任意目录中,然后在解压插件文件找到这个so文件释放即可。第二种方式的代码逻辑是放在了插件中,同时so文件只能放在插件的assets目录中,然后通过把插件文件设置到程序的AssetManager中,最后通过访问assets中的so文件进行释放。
本文主要介绍了Android中关于so的相关知识,主要包括so编译多架构问题,so加载流程问题,so释放问题,so系统兼容问题以及插件中加载so文件的功能解析,看完本文之后,我们需要了解到的知识点:
1、在NDK开发时,可以指定多种架构类型编译出多种类型的so文件。
2、so的加载流程主要是System类中的两个加载方法,最终都会调用Runtime中的nativeLoad的native方法,而这个native方法最终会调用dlopen来打开so文件,然后在调用dlsym方法调用so的JNI_OnLoad方法。
3、关于apk文件在安装的时候释放so文件到本地目录中,主要是结合当前设备的abiList信息(这个信息主要是通过系统属性:ro.product.cpu.abilist值来获取的)和apk中不同类型架构,来决定最终释放哪个类型目录中的so文件,释放完成之后,还需要设置应用的nativeLib路径,以及应用的abi信息,因为这个abi信息在后面启动虚拟机的时候需要用到。
4、因为现在有很多设备已经是64位系统了,但是为了兼容32位的so文件,所以这些64位系统就会在系统启动的时候创建两个Zygote进程,一个是64位的,一个是32位的,当一个应用启动的时候,需要创建虚拟机,那么这时候就会把应用的架构类型传递过去,系统会根据这个类型来交给哪个Zygote进程来处理这个应用启动事件。这样就可以做到so调用的兼容问题了。
5、插件中加载so文件现阶段主要有两种方式,一种是先释放插件中的so文件到本地目录,然后设置DexClassLoader的nativeLib路径;还有一种方式是先释放插件中的so文件,然后调用System.load来加载全局路径的so文件。
正确的获取系统位数的方法是:
Android5.0系统之后,可以通过ro.product.cpu.abilist属性字段值来判断,如果这个字段值中包含了64的话,那么就是64位系统了
Android5.0系统之前,需要通过ro.product.cpu.abi属性字段值来判断,不过5.0系统之前都是32位的,还没有出现64位呢。
获取安卓系统架构类型:
getprop ro.product.cpu.abilist(Android5.0系统之后)
getprop ro.product.cpu.abi(Android5.0系统之前)
copy from 尼古拉斯_赵四 just for record