写点什么

Android 适配 64 位架构,掌握这十个搜索技巧让你的工作效率至上提高十倍

用户头像
Android架构
关注
发布于: 2021 年 11 月 05 日

Google Play:


自 2019 年 8 月 1 日起,在 Google Play 上发布的应用必须支持 64 位架构。


国内:


小米应用商店与 OPPO 应用商店、vivo 应用商店等已经发出通知


  • 2021 年 12 月底:现有和新发布的应用/游戏,需上传包含 64 位包体的 APK 包(支持双包在架,和 64 位兼容 32 位的两个形式,不再接收仅支持 32 位的 APK 包)

  • 2022 年 8 月底:硬件支持 64 位的系统,将仅接收含 64 位版本的 APK 包

  • 2023 年底:硬件将仅支持 64 位 APK,32 位应用无法在终端上运行

32 和 64 位区别

这里需要先说一下 CPU 类型,每种 CPU 类型对应了一种 ABI(Application Binary Interface),常见的 abi 有 armeabi、armeabi-v7a、arm64-v8a、x86、x86_64 等。


  • armeabi: 第 5 代、第 6 代的 ARM 处理器,早期的手机用的比较多,基本可以淘汰了

  • armeabiv-v7a: 第 7 代及以上的 ARM 处理器。2011 年 15 月以后的生产的大部分 Android 设备都使用它

  • arm64-v8a: 第 8 代、64 位 ARM 处理器

  • x86: 平板、模拟器用得比较多

  • x86_64: 64 位的平板


这里主要看 arm 架构的,新的架构能够兼容旧的 abi 对应的 so,例如 arm64-v8a 架构的 CPU 能够运行 armeabi-v7a 架构的 so,反过来不行,这就是为什么现在很多 APP 只包含 armeabi-v7a 的包但是能够在最新的 CPU 上运行。如果以后的 CPU 不再兼容旧的架构了的话,现在只包含 armeabi 或者 armeabi-v7a 架构的 APP 就不能再运行了。


那如果同时包含两种架构呢?如果是支持 64 位系统的机器,会有两个 Zygote(一个 32 位,一个 64 位)进程同时运行。APP 安装的时候根据 lib 目录里面支持的架构和机器自己的 CPU 类型来决定 primaryCpuAbi,在启动的时候会根据安装时候确定的 primaryCpuAbi 的值来决定是从 64 位还是 32 位的 Zygote 进程 fork 出子进程,如果从 64 的 fork,则是以 64 位模式运行。

是否已满足 64 位要求

如果没有使用任何原生代码,那就已经满足 64 位的要求了。如何查看是否有使用原生库?,比较快捷的方法是使用 Android Studio 提供的 APK 分析器。入口在菜单 Build > Analyze APK…


查看 lib 文件夹,如果里只有 armeabi 或者 armeabi-v7a 文件夹,就是只支持 32 位,不支持 64 位。 如果同时还有 arm64-v8a 文件夹,则说明有 64 位原生库,是否与 32 位有相同的功能和质量,还需要进行测试。

快速找出不支持 64 位的原生库

应用内的原生库的来源一般有三处:


  • 第三方库

  • 工程内的 so 文件

  • C/C++ 源码模块


目前很多第三方库已经同时支持 32 和 64 位了,但是有些还不支持,如何找出这部分不支持的库或者文件呢?如果项目中的 so 文件数量很多,就很难通过肉眼的方式来查找,这里提供一个 gradle 脚本可以很方便快速得找出那些不支持 64 位的库。 在主模块的 build.gradle 最后面添加如下代码:


tasks.whenTaskAdded { task ->if (task.name=='mergeDebugNativeLibs') {task.doFirst {println("==========================================


《Android学习笔记总结+最新移动架构视频+大厂安卓面试真题+项目实战源码讲义》
浏览器打开:qq.cn.hn/FTe 免费领取
复制代码


================")def v7a = []def arm64 = []it.inputs.files.each { file ->if (file.absolutePath.endsWith("/jni")) {// println("==========" + file.absolutePath)if (file.isDirectory()) {file.listFiles().each { soFileDir ->if (soFileDir.absolutePath.contains("armeabi-v7a")) {if (soFileDir.isDirectory()) {soFileDir.listFiles().each {println(it.absolutePath)v7a.add(it.name)}}}if (soFileDir.absolutePath.contains("arm64-v8a")) {if (soFileDir.isDirectory()) {soFileDir.listFiles().each {println(it.absolutePath)arm64.add(it.name)}}}}}}}println("v7a size: {arm64.size()}")println("so in v7a, but not in arm64:")v7a.each {if (!arm64.contains(it)) {println("$it")}}println("==========================================================")}}}


然后执行 .\gradlew assembleDebug,这里的 Debug 可以根据实际项目中的 Flavor 进行替换。Demo 工程的输出如下:

用户头像

Android架构

关注

还未添加个人签名 2021.10.31 加入

还未添加个人简介

评论

发布
暂无评论
Android 适配 64 位架构,掌握这十个搜索技巧让你的工作效率至上提高十倍