Android 应用或多或少的会使用so,so 在使用时,也会遇到一些问题,下面整理一些关于so的 概念。
so的编译类型:
Android 只支持3种CPU 类型:x86,arm , mips,不过现在x86和mips已经很少在手机设备使用了,现在的手机基本是arm 体系的。
arm体系,分为32位和64位两种:
1)armeabi/armeabi-v7a : 这个架构是arm 类型的,主要用于Android 4.0 之后,CPU 是32位的。 其中armeabi 是相当老的一个版本,基本已经被淘汰了。
2)arm64-v8a : 这个架构是arm 类型,主要用于Android 5.0 之后,CPU是64位。
通常是生成多种CPU类型的so, 然后分门别类的放在jniLlibs目录下, 其实没有必要这么做。 因为arm 体系是向下兼容的,比如32位的so, 是可以在64位的系统上运行的。
Android 上启动每个App,都会为App创建一个虚拟机,64位的系统在加载32位的so或者App时,会在创建一个64位的虚拟机的同时,还创建一个32位的虚拟机,这样就可以兼容32位的App应用了。 所以在App中,只要保留一个armeabi-v7a 版本的so 就够了。
so 的加载流程:
手机支持的种类存在一个abiList 集合中,一般是3个元素, 第一个元素是arm64-v8a,第二个元素是armeabi-v7a, 第三个元素是
armeabi .
如果检测到arm64-v8a 下有so文件,就只会在arm64-v8a 下加载。 所以64位的arm 手机,想要加载32位的so文件,千万不要在
arm64-v8a 目录下放置任何so 文件, 把so文件都放在armeabi-v7a 目录下就可以加载到了。
加载so的两种方式:
加载so 有两种方法:
1) 使用System.loadLibrary方法,加载jniLibs目录下的so 文件, 加载libhello.so 文件
System.loadLibrary("hello");
2)使用System.load(), 加载任意路径下的so 文件,它需要一个参数,这个参数就是so文件所在的完整路径。 可以将so 放到服务器上,App 下载so 到手机后,再加载so, 这就是so的动态加载技术。
动态加载so 是个很好的技术,只要so 不是立刻加载,就可以全部放在服务器上,慢慢下载,从而减少apk的体积。