由于google 在2019.8 之后,app必须支持64位架构,为了有些新设备只支持64架构。现在,来回顾一下相关知识点和如何支持64位架构;
参考资料:
官网学习资源 https://developer.android.com/distribute/best-practices/develop/64-bit
cpu 架构和支持64位架构:
https://blog.csdn.net/qq_33413264/article/details/82783763 cpu架构介绍
http://www.babajiu.net/kepu/kxjs/201906/9087.html 怎么支持64位
目前常用的架构有这么四种,armeabi-v7a, arm64-v8a, x86, x86_64 ;
Platform | 32-bit libraries folder | 64-bit libraries folder |
---|---|---|
ARM | lib/armeabi-v7a |
lib/arm64-v8a |
x86 | lib/x86 |
lib/x86_64 |
注意:还有一种arm 是armeabi,但现在基本上是armeabi-v7a 较多,并且后者兼容前者。
一个原则:如果你的app 用了C库,native 代码,so 文件,就需要去适配。需要注意的是:不光是你的代码,而且关注你引用的第三方库;对于java 或kotlin 代码则不需要关注。
Analyze APK工具分析
Analyze apk 是as IDE 自带的工具,打开build > Analyaze Apk
或者最简单的在as中双击apk 文件即可,就会进入到分析界面,然后找到lib 文件夹,查看:
看到了arm-v7 表示支持arm架构的32位,没有看到其他的目录arm64-v8a, 则不支持其他的,那我们需要添加支持对应的64位的arm64-v8a.
看到lib 文件下有arm的两种架构,这样表示支持64 .
程序对当前手机cpu架构(比如 armeabi-v7a)做了适配,那手机跑程序时候就直接在这个目录下找对应的so库,如果找不到就直接报错
如果只对armeabi的手机cpu做适配,那么支持armeabi的手机都会去armeabi目录下找对应的so库
如果适配不止一个cpu架构,比如armeabi、 armeabi-v7a 、arm64-v8a这三个,那么一定要确保三个目录中的so库数目一样;第三方库如果支持者提供这三个cpu架构的so库,那非常理想,对应放到目录就可以;
如果适配的上面三个cpu架构,第三方库只提供了两个cpu(比如armeabi、 armeabi-v7a)的库,那也要提供的armeabi的so库,复制一份(armeabi或者armeabi-v7a的so库,因为arm64-v8a兼容armeabi 和 armeabi-v7a)到没有提供的arm64-v8a这个架构目录下;如果不这么做,当应用跑到arm64-v8a架构的手机上时,找不到对应的so库就会报错
具体自己项目适配几种cpu架构,得看app性质,比如微信,主要考虑到兼容,让几乎所有手机都可以适配,另外也相对减少了apk的大小;而另外一个app,比如游戏或者一些对手机性能有要求的app,这种app就挑用户了,只适配到armeabi-v7a,因为目前主流手机都支持armeabi-v7a,就算app支持到只支持armeabi这种架构的手机,app也未必能运行的起来,体验也未必好,算是app放弃也这些用户吧,再说使用只支持armeabi这种架构的手机估计年纪也大了,也不会使用到这个app;
如果只适配一种cpu架构,armeabi(都兼容,但性能有所损耗,如微信和qq)或者armeabi-v7a(目前大部分手机都支持这种cpu架构(王者荣耀));
如果app适配了armeabi、 armeabi-v7a 、arm64-v8a三种cpu架构,以我的手机mate9为例, mate9支持 armeabi、 armeabi-v7a 、arm64-v8a,那么app在找so文件时会从最新的一代的cpu 架构(arm64-v8a)找so文件,如果找不到会直接报错,不会再去armeabi-v7a 和armeabi里面找,一定要确保三个目录中的so库数目一样;如果适配armeabi、 armeabi-v7a,mate9手机上app在找so文件时会从armeabi-v7a找对应so,没有就报错;如果只适配一种,那么手机只要支持这种cpu架构,就会去这个文件夹下找对应的so,找不到就报错,如果手机不支持这种cpu架构就报错
总之一句话:如果app适配了某种架构,则其他的所有native库都需要适配该架构,否则运行到该库的时候会报错,因为他不会往其他的架构中寻找。另外,架构具有往下兼容,比如支持armeabi-v7a,也会支持armeabi, 所以只适配armeabi 也可以,不过没有发挥架构优势。
// Your app's build.gradle
apply plugin: 'com.android.app'
android {
compileSdkVersion 27
defaultConfig {
appId "com.google.example.64bit"
minSdkVersion 15
targetSdkVersion 28
versionCode 1
versionName "1.0"
ndk.abiFilters 'armeabi-v7a','arm64-v8a','x86','x86_64'
其他的写法
ndk {
abiFilters 'armeabi-v7a', 'arm64-v8a' // 指定要ndk需要兼容的架构(这样其他依赖包里其他so会被过滤掉)
}
ndk abiFilters 只会把你列举出来的so库打包到apk 中,但是假如你引用的库不支持64位的,而你配置了64位,这时候就需要联系库的出品方去修改,或者使用ndk abiFilters 过滤掉不支持的架构。现在可以看看百度地图的so 文件(如下图),大多数的native库会提供多种支持
注意:so 库在apk 体积占了很大的部分,比如图2中显示只支持一种架构,so文件占了20%,如果支持四种常见架构,那么app的体积会剧增,所以,google play 也不是要求我们支持所有的 64 位架构,但是对于已经支持的每种原生 32 位架构,就必须包含对应的 64 位架构。
例如:
这就要求我们有对应的目录,并且目录中包含对应的 so 文件。APK 中提供了完备的 ABIs 支持,运行的之后,会选取对应的最优支持进行加载和使用。
需要注意的是,有时候我们将 32 位的 so 复制到 64 位中,运行不会出现异常,但是这依然存在隐患。最好的办法是根据不同的架构,编译对应的 so 文件,原则上,我们的目标是确保应用可以在仅支持 64 位架构的环境中正常运行。
# A successful install:
> adb install --abi armeabi-v7a YOUR_APK_FILE.apk
Success
# If your APK does not have the 64-bit libraries:
> adb install --abi arm64-v8a YOUR_APK_FILE.apk
adb: failed to install YOUR_APK_FILE.apk: Failure [INSTALL_FAILED_NO_MATCHING_ABIS: Failed to extract native libraries, res=-113]
# If your device does not support 64-bit, an emulator, for example:
> adb install --abi arm64-v8a YOUR_APK_FILE.apk
ABI arm64-v8a not supported on this device
测试: