<
APK包体积优化
>
上一篇

Gradle构建问题解析
下一篇

Android App的安装过程

分为两个部分:安装包监控,安装包大小优化

APK包体积优化

一、安装包监控

1.Android Studio的APK Analyser

这是AS提供的一个APK检测工具,通过它可以查看一个APK文件内部各项内容所占的大小,并按照大小排序显示。因此很容易观察到APK中哪一部分占用了最大空间。APK Analyzer的使用很简单,只要将需要分析的APK文件托人AS中就行,显示内容类似下图:

1

从上图可以很明显看到图片占用了比较大的资源空间,因此可以针对性地对其做压缩优化等操作。

实际上APK Analyzer的作用不光是查看APK大小,从名字可以看出它是用来分析APK的,因此可以使用它来分析一些优化APK的目录结构,代码规范,甚至是使用了哪些动态库技术

2.Matrix中的ApkChecker

ApkChecker是腾讯开源框架Matrix的一部分,主要用来对Android安装包进行分析检测,并输出较为详细的检测结果报告。正常情况下我们需要下载Matrix源码,并单独编译matrix-apk-cananry部分。但是如果想快速使用ApkChecker,可以直接在网上下载其ApkChecker.jar文件,然后创建一个配置文件.json即可。

官方格式如下:

2

有几个地方需要我们去替换:

ApkChecker的好处是可以命令行使用,这样我们可以很方便将其配置在自动化集成系统中,并对最终生成的APK文件进行分析,将产出报告发送到指定位置。

Matrix也是有一定的缺陷,比如使用UnusedAssetTask检索assets中的资源,这个过程只是调用了DexFileFactory.loadDexFile加载dex文件,所以只会去搜索java文件中的引用。如果在assets目录下有一个.json文件,此.json文件中记录assets文件夹中的其他图片路径,然后在Java代码中通过AssetManager读取这个.json文件,循环遍历引用的图片,对这种方式Matrix是检测不到的。

二、安装包优化实践

1.删除无用文件

使用Lint查看未引用资源。Lint是一个静态扫描工具,它可以识别出项目中没有被任何代码所引用到的资源文件。使用方式:AndroidStudio -> Analyze -> Inspect Code,然后选中整个项目即可

3

如果项目中有未被使用资源,则Lint会在窗口Inspection Result中显示,类似如下:

4

下面两个选项可以在项目编译时期减少被打包到APK中的文件,使用shrinkResource能够在项目编译阶段,删除所有在项目中未被使用到的资源文件。但是需要将minifyEnabled选项置为true

使用resConfig限定国际化资源文件,有时我们使用到的三方库中可能会对各种国际化语言进行支持,但是我们自己的项目只支持某个语言,比如中文,那我们可以在gradle的defaultConfig中使用resConfig来限制打包到APK中的国际化资源文件,具体如下:

5

2.文件优化

a.关于静态图片优化

优先使用VectorDrawable图片,如果UI无法提供VectorDrawable图片,那么webp格式是一个不错的选择。AS也支持将png或jpg转为webp格式,如下:

6

b.关于动态图片优化

实际上webp也可以做动态图,只是目前对webp动图支持的三方库并不多,Google的Glide对webp支持也不是很友好

但是Google推出了一套C++依赖库,上层开发人可以基于此库的基础上使用JNI来解析Animated webp图片,并将解析出来的每一帧分装成一个Bitmap,并根据解析出来的时间差值动态显示相应的帧Bitmap即可。如果JNI不熟也可以使用Github的Android-WebP。开发人只需使用WebImageView控件并指定图片路径即可

另外针对动态图片,我们也可以借鉴游戏发开相关的TextureAlas这种图片格式,就是将多个序列图按照一定的排放位置合成到一张图片中,如下图片:

7

并且跟随图片一起生成的还有一个用来对其解析的文本配置文件。主要是用来识别合成图中的路径,每张帧图片的顺序,位置等。一般情况下配置文本的格式如下:

8

这套方案主要是借鉴了一个轻量级游戏引擎libgdx的实现思路,解析上述的TextuewAtlas图片,将生成的Textuew渲染到Bitmap上展示每一帧内容。如下:

9

这套方案优点是图片压缩效果比webp和gif更加显著,生成的合成图片比webp和gif更小。但是缺点是使用门槛较高,需要了解OpenGL

c.关于引入三方库

在App中会引入各种三方的“轮子”,但是在引入之前最好权衡下是否需要将其代码全部引入,造成不必要的代码或者资源也被打包到APK中

例如在上面说到的webp动图实现方案,使用Google推荐的libwebp,但是这个库不光是为了解析webp图片,还有很大一部分是为了实现生成一个webp图片,这部分代码不是我们需要的,因此需要删除,最终编译后生成的so库大小可以减少1/3左右

d.关于App Bundle

在项目中使用App Bundle中比较好用的选项–Dynamic Asset Delivery。这个功能本来只是针对安装包超过100M的App,但是不影响我们使用这套方案进行安装包优化。

具体做法是将大部分assets中的资源使用无损压缩的方式,压缩成一个.obb格式的文件,然后每次发布App时都将此obb文件设置为APK的bundle文件,这样也可以减少用户实际的安装包大小。

但是App Bundle只适合在Google Play Store上发布的项目,国内还是通过各家的插件化方案来实现动态部署,一定程度上也可以算作减少安装包大小的方案

总结

主要学习了在项目中关于安装包优化的一些实践总结,主要2方面:

  1. 安装包的监控:主要介绍了几个可以用来分析安装包大小以及详细内容的工具:Apk Analyzer和ApkChecker
  2. 安装包优化实践:主要思路就是删除无用资源或代码,并对资源文件进行相应压缩。实际上除了资源文件,代码部分也是可以进一步的优化,比如使用Proguard或者直接使用R8编译方式。
Top
Foot