片多多64位升级之路

1.为什么要做?

为了满足厂商的要求和市场趋势,64位的安装包升级无可避免。为了解决片多多在64位机型上的性能和稳定性问题,需要在工程中支持64位安装包,并能准确输出64位包,最后进行精准分发。

2.收益是什么?

  1. 应用在64位的机器上运行,有专门的64位包,可以让内存分配得更大,应用更好运行,给了应用更广阔的创新空间,经过兼容更多的更新的硬件来提高软件的全体性能
  2. 基于第一点,应用在64位上运行的crash率会降低
  3. 合理满足了各商店对于应用上架的要求

3.需要做什么?

  1. 工程升级至64位
  2. 流水线改造--增加支持64位打包
  3. 升级策略精准分发:其中包含商店渠道、应用内升级渠道、分发渠道。

1⃣️商店渠道自带支持:根据用户机型情况判断给用户推送32位或者64位包

2⃣️应用内升级准备支持:根据用户机型情况判断让用户下载32位或者64位包来安装

3⃣️分发渠道:渠道分发目前优先32位包,64位包由升级行为带动

4.不良影响及解决

4.1 有不良影响?

  1. 64位的包体积会比32位大,且可能大很多

4.2 不良影响的解决方案

  1. 对应用中使用的各种库采取动态加载方式(需要对不同的第三方库进行梳理,看这些库是否支持)
  2. 其他的就常规体积优化策略
  3. 差异化分发,64位与32位包分开提供,为两份安装包

5.64位app运行原理

5.1 什么是64位适配?

64位适配,是指在64位的设备上运行64位的进程。

5.2 如何做到让我们的app运行在64位进程上?

64位的设备所承载的系统有两个Zygote进程(Zygote是在init进程启动时创建的,它又称为孵化器,它可以通过fork(复制进程)的形式来创建应用程序进程和SystemServer进程),一个32位的Zygote,一个64位的Zygote,两者同时运行在系统上。

app在安装进手机的时候,其实是一个解包的过程(apk其实就是一个安装包),解包之后,在本地的文件中会有一个文件夹,名为“lib”。系统的PMS服务(PackageManagerService)就会通过它的scanPackageDirtyLI方法进行遍历lib文件夹下的目录,目录内存放着so库,如下图所示:

库中可能包含了“arm64-v8a”、"armabi"、“armabi-v7a”等文件夹,每个文件夹内都会有对应的so库。PMS根据文件夹列表再结合手机硬件所支持的abilist列表,选择最适合的文件夹下的so加载。这个选择方式最终的结果是输出了一个叫primaryCpuAbi的值。注意:如果PMS决定了一个文件夹之后,其他文件夹它是忽略的。

当app真正启动的时候,ActivityManagerService(ActivityManagerService,以下简称AMS,服务端对象,负责系统中所有Activity、Service的生命周期以及BroadcastReceiver和ContentProvider的管理)根据前边得到的primaryCpuAbi值,调用了进程的start()方法来确定这个app是需要使用64位还是32位的zygote进程来fork出应用进程。若该应用进程是由32位创建,那么则运行在32位进程上,64位同理。

那么,划重点就是,64位的适配其实就是apk中lib文件夹下的so库的适配,java的代码是同一份,无论在64位还是32位上均可运行,而so库则不同,专门适配的版本,无论是性能和效率都会得到更高的发挥。这里要注意一点,一旦运行了64位的进程,那么此时去加载32位的so库,是无法实现的,32位亦然。

6.片多多适配

6.1 包的构建

方案一、构建一个支持所有abi类型的apk。

优点:满足任意机型的安装

缺点:包体积变得特别大,因为是支持的abi数*原本的包体积大小。按照现在片多多的包体积大小为47MB,想要以此方式支持64位的话,包体积将会>94MB。

实现方案:在build.gradle里的ndk中加上相应的abi类型即可

方案二、为每个abi单独构建apk

优点:包体积几乎保持不变

缺点:需要根据不同的情况,下发合适的apk到对应的用户设备上进行安装

方案:在gradle里单独配置不同的buildTypes,然后利用修改脚本,打出不同的包

gradle中的脚本设置如下:

android {

    buildTypes {

        debug {
 
        // 其他配置

                matchingFallbacks = ['debug']

                ndk {

                        abiFilters "armabi"

                        }

                }

        debug64 {

        // 其他配置

        matchingFallbacks = ['debug']

                ndk {

                        abiFilters "arm64-v8a"

                        }

                }

        release {

                // 其他配置

                matchingFallbacks = ['debug']

                ndk {

                        abiFilters "armabi"

                        }

                }

        release64 {

                // 其他配置

                matchingFallbacks = ['debug']

                ndk {

                        abiFilters "arm64-v8a"

                        }

                }

        }

}

打包脚本sh文件中的设置如下:

gradle $command"Debug" --stacktrace

gradle $command"Debug64" --stacktrace

gradle $command"Release" --stacktrace

gradle $command"Release64" --stacktrace

最终选择:根据片多多的市场情况,目标用户群体对包体积大小的敏感度很高,所以方案一的包体积大小是无法接受的,那么只能选择方案二

6.2 升级方案

6.3 流水线的改造

由于目前的请求只支持下发一个安装包的链接,就需要进行改造。根据6.2所示,请求的参数中带上了是否架构的标记,便于后台针对不同的参数进行下发不同的安装包链接。

就这样完成了一键式的集成分发流程

后续要接入:

1、动态化so库下发能力

注意点:

任何接入的库都需要查看是否分别用32位与64的so存在。需要查找64位与32位的so库的区别的,快速方式可以使用以下工具:EasyPrivacy:https://github.com/pengxurui/EasyPrivacy。

使用日志分析即可:

版权声明:
作者:黎明破晓
链接:https://jkboy.com/archives/15294.html
来源:随风的博客
文章版权归作者所有,未经允许请勿转载。

THE END
分享
二维码
打赏
海报
片多多64位升级之路
为了满足厂商的要求和市场趋势,64位的安装包升级无可避免。为了解决片多多在64位机型上的性能和稳定性问题,需要在工程中支持64位安装包,并能准确输出64位包,最...
<<上一篇
下一篇>>