最近使用三方框架,需要导入so包,不知道应该哪个型号的,查了一堆感觉懵逼,直接记录下用以备忘。
个人理解,若有不对,希望指正
兼容方案:https://www.cnblogs.com/janehlp/p/7473240.html
是什么:
Java是有极限的,Java只在JVM虚拟机上做事,JVM无法直接操作系统,也没有提供系统API给Java开发者。
当Java无法完成任务,需要借助C语言直接操作系统时,就需要把C语言写入项目,C代码存放的文件类型就是.so文件。
如何用C语言操作系统呢,需要API啊,google提供了 NDK 用于C语言对系统进行操作。
兼容问题:
手机厂商制造了太多的手机,市面上存在或老的或新的手机,各种各样的手机cpu都被使用着。
cpu型号那么多,那开发者怎么依赖cpu写程序呢,肯定要给套不能经常变的接口哇,于是cpu厂家提供了一套接口(ABI)给开发者们使用。
但后来cpu厂家又遇到了问题,cpu要更新,各种小的大的更新,多了很多新功能,原来的接口用不了新功能肯定要更新啊。
cpu厂家可不像google独自掌管Android,它们写接口可没商量,于是各种各样的接口都出来了,互相不兼容,针对A厂家写的程序没办法跑在B厂家上(arm系列、x86系列、mips系列)。
还好最早它们都是用 armeabi 接口,不然每次写底层都至少三套了。
SDK 和 ABI 的相似和区别
ABI 是由 cpu系统厂商提供的,是用于操作系统的接口,每当厂商做的 CPU 出现了重大更新,它们就会更新升级 ABI 以供开发者去使用新的功能,就和SDK一样。
但 ABI和SDK 还是有区别的。SDK 被开发时会考虑以前的 SDK,所以我们可以用最新的 Android v28 去开发 Android v19 的手机。
Android手机内存放的接口代码不止最新的接口,还包含历史的接口,所以我们可以用老旧的 Android v19 去开发 Android v28 的手机。
cpu 被设计时也会考虑以前的 ABI,所以最新的 armeabi64 设备能运行 armeabi 最老的代码。
但可能基于硬件或其它什么的原因,ABI开发时没法适配以前的cpu,所以最新的 armeabi64 代码没法跑在 armeabi 最老的设备上。
这就有坑了,你市面上老的cpu armeabi 还有人在用,我不能像android那样只写个 armeabi64 的代码,那样只有最新的手机才能运行,但我可以写个最老的 armeabi 代码,做到所有手机都能运行。
能运行不等于效果好,64位的 armeabi64 cpu 跑 32位的 armeabi 代码,就像给你个计算器你却只会用算盘一样,无法发挥全部性能,甚至可能出错误(https://www.cnblogs.com/janehlp/p/7473240.html)
所以最保险是每个ABI的so都写一份。
兼容支持表: (https://www.jianshu.com/p/cb15ba69fa89)
ARMv5,ARMv7 (从2010年起),x86 (从2011年起),MIPS (从2012年起),ARMv8,MIPS64和x86_64 (从2014年起)。
armeabi设备(ARMv5) 只兼容armeabi
armeabi-v7a设备(ARMv7) 兼容armeabi-v7a、armeabi
arm64-v8a设备(ARMv8) 兼容arm64-v8a、armeabi-v7a、armeabi
X86设备 兼容X86、armeabi
X86_64设备 兼容X86_64、X86、armeabi
mips64设备 兼容mips64、mips
mips只 兼容mips
专业术语介绍: (Java -> C -> 系统cpu)
SDK:Software Development Kit 软件开发工具包 //顺便提一下
JNI:Java Native Interface Java操作Native层(底层)接口
NDK:Native Development Kit Native层(底层)开发工具包
ABI: Application Binary Interface 应用二进制接口
Java 可没办法直接调用 C 代码,需要通过 JNI 来调用 C 代码
C 也没法直接操作系统,需要借助 NDK 提供的接口与环境来操作系统
系统是提供了接口以供操作的,即 ABI;NDK 就是在 C 调用的时候去调用系统提供的 ABI。
————————《总结就是》————————
Java 通过 JNI 调用 C | Java 通过(Java操作Native层接口)调用 Native层的 C
C 通过 NDK 调用 ABI | C 通过(Native层开发工具包)去调用(应用二进制接口)
ABI 操作cpu系统。 | 最终(应用二进制接口)让cpu系统执行任务
其它开发中需要注意的:
1、写好的so文件放在 libs/armeabi、libs/armeabi-v7a、libs/arm64-v8a、libs/mips、libs/mips64、libs/x86、libs/x86_64。
2、一个名字的so文件必须在每个文件夹内都有,否则就会报错,比如 libs/armeabi 里有个 a.so,但 libs/x86 是空的,就会出错(https://www.jianshu.com/p/cb05698a1968)