2022/04/27 号更新:

补充一个关于适配 64 位架构的必要性:

ARM 已逐步取消其 CPU 核心对 32 位的兼容,在骁龙8 Gen 1 处理器中,1 个 3.0GHz 的 X2 超大核和 4 个 1.8GHz 的 A510 中核则均不兼容 32 位应用,我想后面更新的芯片出来应该会慢慢取消的,这也就倒逼开发一定要做出适配。



华为应用市场近日给开发者发布了一则通知,通知内容如下:

【重要】关于安卓应用在华为应用市场发布必须提供64位版本的通知
尊敬的开发者,您好!
为了更好地提升安卓应用性能体验、降低安卓应用的功耗影响,华为应用市场将全面推行安卓应用升级为64位版本,请您注意及时升级替换应用包体,具体节奏如下:
1)2022年2月1日起,在华为应用市场新上架/升级的游戏及应用,必须包含64位版本,华为应用市场不再接收仅包含32位版本的应用;
2)2022年9月1日起,华为应用市场将不再接收包含32位版本的应用。
我们建议您可以通过以下方式进行适配:
App Bundle应用分发:上传aab格式的软件包,App Bundle在分发阶段,将根据对应设备的CPU类型,对aab包进行拆分,打包成对应apk后进行灵活分发,并能有效减小应用包体体积。点击查看App Bundle详情介绍。
仅上传64位包体:您也可以直接上传64位的APK包体,以确保应用在64位机型中的最佳性能体验。
注:在过渡期间,可将32位和64位版本打包在一起,以确保其在不同CPU架构下的性能体验。
对此,如您仍有任何疑问,请发送邮件至 agconnect@huawei.com 或通过华为AppGallery connect互动中心进行咨询,我们将及时进行解答。
华为开发者联盟
2021年11月18日

总结起来就是:2月份之后,不允许应用只包含 32 位版本,9 月份之后,不允许应用包含 32 位版本。

一、简单说一下应用包含 32 位版本和 64 位版本是什么意思。(换个说法讲,就是我们的 app 支不支持 32 位,或者支不支持 64 位的 CPU 架构)

1、移动端的 CPU 架构,目前应该是 arm 和 x86 一统天下的局面,而针对手机端,现在绝大部分使用的都是 arm 旗下的 CPU 架构(不要问为什么,问就是因为功耗更低,性能更好)

2、对于 32 位和 64 位的 处理器,arm 和 x86 又分别有不同的 CPU 架构,如下:

32 位: armbi、armbi-v7a、x86

64 位:armbi-v8a、x86_64

那么如何查看手机的 CPU 架构呢?

通过手机终端命令就可以查看到,命令:cat /proc/cupinfo

下图是我用自己手机试的,可以清楚的看到架构是 arm-v8 的,也就是 64 位的 处理器,并且共 8 个进程,是 8 核的。

二、判断我们的 app 是不是支持 64 位系统的

1、如果你的 app 比较简单,就是纯 Java 或者纯 Kotlin 代码构建的,并且不包含其他第三方的 so 库,那么它天然就是支持 64 位架构的,开发者无需做适配。

2、通过终端查看当前 app 是否运行在 64 位父进程上。在 64 位的 Android 系统上,会同时运行两个 zygote (zygote 是 Android 系统创建的一个 java 进程,它是所有 Java 进程的父进程),一个 zygote,一个 zygote64,因为 64 位的 Android 需要同时运行 64 位和 32 位的 app。

通过命令行 :adb shell ps | grep zygote可以查看当前运行的父进程,如图:

过滤当前父进程的进程 ID,就可以知道自己的应用是运行在 64 位进程还是 32 位进程上了,可以看到当前我的 app 是运行在 32 位进程上的(当然你得知道 app 的包名是什么),如图:

3、通过查看打包进 apk 里的 .so 文件,也可以判断是否支持 64 位。

(1)如果你是开发者,通过 Android Studio 打开 .apk 文件,查看 lib 目录下是否存在 arm64-v8a 或者 x86_64 库,以此判断是否支持 64 位,下图可以看到目前我的 app 是没有 64 位的库的。

(2)通过解压 APK 查找原生库,也可以看出是否包含 64 位版本的库。

命令行:zipinfo -1 your_apk_file.apk | grep \.so

如下图,同样看出 APP 不包含 64 位的库,也就是不支持 64 位。

4、 通过 adb 命令安装 apk 到手机上。当 apk 不包含64 位库的时候,会报错。

命令行:adb install –abi arm64-v8a your_apk_file.apk

结果如图:

三、使我们的 app 支持 64 位系统。

  • app 对当前手机架构(比如:armeabi-v7a)做了适配,那么手机运行 app 时会直接在这个目录下找对应的 so 库,找不到就会报错(比如闪退)
  • 如果只对 armeabi 的手机 CPU 做适配,那么支持 armeabi 的手机都会在该目录下找对应的 so 库。(从上面的截图可以看到目前这款 app 只包含 armeabi 的 so 库,并没有对 armeabi-v7a 和 arm64-v8a 做适配,但是后者都是兼容前者的
  • 如果 app 用到了 C库、native 代码、so 文件,就需要做适配。现在很多 app 都很难避免依赖到 第三方 SDK,通常 SDK 也会提供几种不同架构的 so 库供我们适配用。

(1)首先,要适配哪个 cpu 的架构,就要程序中就要有对应的目录,比如我的项目只适配了 armeabi,就只有一个 armeabi 目录:

这里插播一条小知识点:现在 andorid 项目的 jni 目录是在 src/main/jniLibs,但是因为很多老的项目是从 eclipse 迁移过来的,很多人也习惯了将 so 库放在 libs 目录下 ,这个在 build.gradle 文件配置一下即可。

(2) 在 build.gradle 中配置 ndk,来控制要将哪些目录的 so 库打包进 apk 里。

(3)目前手机架构最多的应该是 arm64-v8a 、往前几年的 armeabi-v7a,和比较旧的 armeabi,如果适配了这三个架构,那么就要保证这三个目录下的so 库数目一致(如果只有文件夹但是没有 so 库,打包 apk 时不会将该目录打包进去)

(4)一般来讲,对每个架构都进行适配,就可以达到最好的兼容效果,但是适配的架构越多,apk 文件就越大,这个就要看每个 app 自己的取舍了。上述的架构,都是向前兼容的,也就是说如果第三方只提供了 armeabi 或者 armeabi-v7a 的 so 库,那么为了适配 arm64-v8a ,可以将 armeabi 或者 armeabi-v7a 的 so 库拷贝一份到 arm64-v8a 的目录里,也是可以正常运行的。像当前展示的这个 app 只适配了 armeabi 架构,绝大多数手机都是兼容的,但是会带来性能上的损耗,通俗点讲,就是没有发挥当前这台手机 cpu 该有的性能。所以在条件允许的情况下,还是建议大家根据自己的需求进行比较好的适配。

(5)一定要保证每个目录下 so 库文件数目的一致性

举个例子:如果适配了 arm64-v8a ,那么手机运行时就会到该目录下寻找 so 库,找不到就会报错(现象一般都是闪退),不会再往 armeabi-v7a 或者 armeabi 目录里找了。

四、使用 App Bundle

App Bundle 是 google 官方在 2019 年推出的一种发布格式,并且规定在 2021 年 8 月起,在 Google Play 发布应用就需要使用新的发布格式,即不再接收新的应用以 apk 的形式发布。

简单地讲 App Bundle 的优势就是将功能模块化,可以减少 apk 的体积,还能根据配置推送特定的功能,而后将 apk 的生成和签名交给 Google Play 来完成。

虽然说国内大部分的开发者和 Google Play 应该是没啥关系的,但是有新的更好用的东西我们也应该试试,而且华为应用市场也是支持通过 App Bundle 来发布应用的。

目前我还没有试过,当前项目虽然也是通过不同 bundle 来实现功能模块化,最后打包成 apk 的,但是其实在功能解耦上做的很不好,而且随着能力不同的开发经手,项目的模块化显得荡然无存,主 bundle 日渐臃肿,所以我还没有真正着手对这一块进行改造。

想尝试用 App Bundle 进行发布的小伙伴可以到开发者网站学习一下,如果本身项目架构和编码这一块基础很好的话,应该是不难用起来的。

等后面着手改造项目,用上了 App Bundle 之后,再来补充这一块的内容吧。