android中so文件小结

介绍

so shared object(共享的对象)缩写一般我们也叫动态链接库,在c++中可以把写好的code编译成 .so文件给其他平台使用的。so文件是机器可以直接运行的二进制代码,大到操作系统小到一个专用软件都离不开so。so是与平台相关的二进制机器码,与ABI(Application Binary Interface)相对应,一个ABI表示相应的CPU的指令集与内存页管理,也对应于不同的C运行环境,所以so是有不同的系统版本的。

架构类型

  • 随着Android系统的快速发展,搭载Android的硬件平台也早已多样化了(对比WinTel联盟,直到2012年才新发展了Windows RT来适配ARM平台,2015年的Win10才进入 Raspberry Pi 2这类基于ARM的新型设备中),现在已经运行在7个ABI:armeabi,armeabi-v7a (armeabi-v7a-hard),arm64-v8a,x86,x86_64,mips 和 mips64。
  1. armeabi设备只兼容armeabi;
  2. armeabi-v7a设备兼容armeabi-v7a、armeabi;
  3. arm64-v8a设备兼容arm64-v8a、armeabi-v7a、armeabi;
  4. X86设备兼容X86、armeabi;
  5. X86_64设备兼容X86_64、X86、armeabi;
  6. mips64设备兼容mips64、mips;
  7. mips只兼容mips;

可以看到armeabi的SO基本可以上大部分ARM平台架构上使用,如果在非armeabi上进行运算会有性能损耗,中间CPU多了一个转换的环节so~ 最好是根据目前市面情况来做适配,目前来看armeabi-v7a覆盖90%的手机ARM架构。

  • 64位的CPU架构总能向下兼容其对应的32位指令集,如:x86_64兼容X86,arm64-v8a兼容armeabi-v7a,mips64兼容mips;

使用优势

  • 开发Android应用时,有时候Java层的编码不能满足实现需求,就需要到C/C++实现后生成SO文件,再用System.loadLibrary()加载进行调用,这里成为JNI层的实现。
  • so机制让开发者最大化利用已有的C和C++代码,达到重用的效果,利用软件世界积累了几十年的优秀代码so是二进制,
  • 没有解释编译的开消,用so实现的功能比纯java实现的功能要快so内存分配不受Dalivik/ART的单个应用限制,减少OOM

存放方式

androidStudio下so文件有二种方式存放
第一种默认的
目录是src/main/jniLibs/armeabi | x86 | v7 下面
这种是系统默认加载so去找的路径,如果没有找到将会报错!

1
2
System.loadLibrary("openconnect");
System.loadLibrary("stoken");

第二种指定加载路径
libs/armeabi | x86 | v7 下面
放libs文件下面需要在项目gradle下面指定路径

1
2
3
4
5
6
7
android{
sourceSets {
main {
jniLibs.srcDirs = ['libs']
}
}
}

总结

知道了为什么用so后剩下就是怎么去适配市面上不同的ARM架构的手机了,前面列出的arm架构可以看到 arm架构基本上可以兼容90%的手机架构了, 如果有特殊考虑也可以加入其它架构的so但是会对apk包体积上有影响。