您的位置:首页 > 移动开发 > Android开发

Android so库研究

2018-03-22 09:40 218 查看

一个so库引起的问题:

我们项目一直是运行在32位系统的定制设备上,然后有一天,老板说我有一个华为平板,把项目移植到这个设备上看看效果,结果运行的时候有个出错提示:xxx.so is 32-bit instead of 64-bit,那怎么解决呢?还等着要给老板演示看呢。

引发的思考:

既然提示说这个so库不是64位的吗?那我就给你找一个64位的so库出来,很遗憾,厂商根本没做64位的so库,只有一个32位的。

既然第一条想不通,我就开始回想:为什么厂商不提供64位的,他们应该知道android手机有的是32位,有的采用64位,但是既然只提供一个32位的,那么说明64位的android手机肯定是向下兼容的,那么现在为什么没有兼容?为什么在没有64位so库的情况下,没有智能去查找32位的so库?

探索so库问题:

cpu架构:

armeabi/armeabi-v7a:arm类型,主要用于Android4.0之后的,cpu是32位的

x86/x86_64:这个架构是x86类型的,有32位和64位,占用的设备比例比较小

arm64-v8:这个架构是arm类型,主要用于Android5.0之后,cpu是64位的

如何知道自己设备是支持哪种cpu的架构呢?

1.通过Build.SUPPORTED_ABIS

String[] abis = Build.SUPPORTED_ABIS;
if (abis != null) {
for (String abi : abis) {
Timber.d("[ supported abi: %s" + abi);
}
}


2.命令行方式



从这里应该可以看出来,定制版的设备支持armeabi-v7a,armeabi,cpu是32位的;而平板支持arm64-v8a,armeabi-v7a,armeabi,cpu是64位的,所以当项目中做了既支持64位,又支持32位的cpu架构时候,如果是64位的系统,会去查找64位so库,而不是查找32位的so库,所以就报了is 32-bit instead of 64-bit

那么为什么会这样呢?

这个底层分析,有篇文章分析得非常到位:

http://www.wjdiankong.cn/archives/849

精简其过程如下:

(1)先获取设备中所支持的cpu架构类型,拿到abiList

(2)把apk文件中libs目录下的so库和cpu架构类型对应并返回一个索引值index

(3)设置包信息的cpuAbi是abliList[index]

比如说:cpu架构支持arm64-v8a,armeabi-v7a,armeabi,然后看项目中是否有对应的 如果文件夹:arm64-v8a,armeabi-v7a,armeabi是这种,索引值是0,代表64位cpu架构;如果文件夹是:armeabi-v7a,armeabi,索引值就是1,代表32位cpu架构。



(4)应用启动的时候,获取包信息中的cpuAbi类型,这个会告诉Zygote要创建多少位的虚拟机,如果设备是64位的,cpu架构也是64位的,就创建64位的虚拟机;如果设备是64位的,但是只有32位的cpu架构,就会去创建32位的虚拟机。

所以我们经常看到的is 32-bit instead of 64-bit 产生的原因就是:系统是64位的,然后cpu架构中也放了这个arm64-v8a文件夹,然后把32位的so库还放在这个文件夹下,当然就会提示so库不是64位的错误。如果你只有32位的so库,正确的做法就是,不要去创建arm64-v8a了,只是创建armeabi-v7a,armeabi即可。

(5)如果项目中已经创建了64位和32位的jniLibs目录,但是又只有32位的so库,那么如何只让它查找32位的so库呢?

defaultConfig {
...
...
...
ndk {
abiFilters "armeabi-v7a"//只支持32位
}
}
sourceSets {
main {
jniLibs.srcDirs = ['libs']
}
}


.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  so库 cpu架构