Matrix源码分析系列-如何解析应用安装包

前言

首先我们思考一个问题,为什么要解析安装包?目的是什么?什么原因促使我们做这件事?

  • 减小包的体积,产品或运营同学认为,包体积越小,越能提高下载量
  • 应用市场限制,如App Store、Google Play 都有相关包体积的规定,都是以更小为主
  • 减少内存占用,不管是Rom还是Ram 肯定是随着应用包的体积增加而成正比增加,所以减小包体,也是在间接优化内存占用

我们找了这么几个原因,促使我们做这件事,确实在实际的工作中,特别是toC的小伙伴,更加明显,他们一直在做包体积的优化,那么要优化体积,那肯定是要知道包的构成,这样才能有合适的优化方法,那么我们再来看看包的构成。
<a name="3FVJ8"></a>

包的构成分析

我们利用Android studio的可视化工具,打开了一个普通的apk安装包,如下 <br />

image.png
<br />为了更有说服力,我拿了WX的包来分析看,如下:<br />
image.png
<br />通过两张图,我们分辨出包的大致构成如下:
  • Dex、so库。且WX的SO库只保留了armeabi-v7a架构的包,已占比50%,可见很高。
  • r资源文件及assets ,存放图片,音频,资源文件的位置
  • resources.arsc 文件也达到了6.8MB,这是资源索引表,开发中Resources就是通过resources.arsc把Resource的ID转化成资源文件的名称,然后交由AssetManager来加载的,它是由AAPT工具在打包过程中生成。
  • META-INF 签名信息
  • AndroidManifest.xml 清单配置文件

整体来看,占比较高的就是 Dex、So、r、assets、resources.arsc,那么我们优化,肯定是要从这几个方面入手对吧。
<a name="AN1Z1"></a>

如何减小安装包的体积

1.资源压缩

对大图进行无损压缩,对不需要alpha通道的png图,压缩成jpg,或者使用更小的webp图片:webp介绍<br />对于assets中存储的音频文件可以选择远程依赖,第一次下载后做缓存处理

2.通过编译器缩减,混淆

利用R8 编译器,进行代码缩减、资源缩减、混淆处理等,都可以有效的减小包体积,具体介绍请看:缩减、混淆处理和优化应用<br />注意:R8编译器要求 Android Gradle 插件 3.4.0 或更高版本

3.resources.arsc文件缩减

这个文件怎么缩减呢?经过查询资料发现,该文件对于不同的语言,不同的编码格式有一定的影响,直接说结论:

  • 对于纯英文来讲,建议使用utf-8格式编码
  • 对于中文来讲,建议使用utf-16

具体实现操作请看: aapt 相关命令

4.so库精简

通过上面第二张图我们发现,wx的so库只保留了armeabi-v7a架构,这也是目前最流行的架构,wx这么大的用户量都敢只保留一个,你有啥不敢的。将x86、arm64-v8a果断删了吧。这是表面的优化,更深层次的就需要对so库代码精简,如:抽离独立的库,减少冗余代码。还有建议C++运行时库使用stlport_shared,同样可以减少包大小,且可以节省一点内存,这种方式请注意:应用程序需要先加载所需要的共享库,然后再加载依赖此共享库的其他原生模块

static{
     System.loadLibrary("stlport_shared");
     System.loadLibrary("xxxxx");
}

5.Dex文件数量优化

在我们使用multiDex后,或者说方法数达到65535之后,不得不对代码进行分包,分包会带来什么问题呢?

  • method id 分配不合理导致更多的Dex量,由于method id 的大量冗余导致每个 Dex 真正可以放的 Class 变少。
  • 信息存储冗余,因为每个dex中都存在调用的方法的详细信息,举个例子,如果一个class method被其他dex引用到的话就会导致 这个class不光是在自己的dex中存在方法信息,被引用到的dex中也存储了class的方法信息,这样造成冗余,冗余过多就会导致dex数量增加。

知道了问题如何解决呢?答案就是尽量让方法的引用都在同一个dex中,这样就可以减少冗余,减少dex的新增,目前最优解建议使用:Facebook 的一个开源编译工具ReDex,具体使用方法建议去看文档:https://github.com/facebook/redex,这里就不展开描述。

6.Dex压缩

此方法还是来源于Facebook的包,它真正的dex代码放到了assets目录,且通过xz 压缩算法(该算法压缩率比 Zip 高 30% 左右),并通过应用首次启动的时候解压缩,并利用多线程解压缩方式,耗时并没有那么明显。

小结

说了这么多的优化放法,如果想做到极致,肯定还有方法,但我们现在处于5G时代,大家还会对10M甚至说100M有感觉吗?这就需要于用户体验之间做一个权衡,一些极致的优化肯定是会降低用户体验的,需要按需而行吧。

Matrix App Checker

终于进入正题,我们了解了包的结构和常见的缩减方法,那么App Checker到底可以为我们提供什么样的帮助,来辅助我们进行缩减呢?随我一探究竟。

代码目录

image.png

<br />可以看到libs中引入三方jar包- apktool-lib-2.4.0.jar , 它的作用就是将apk反编译出来,产出dex、libs、manifest等文件。再往下看代码

  • exception目录中 抽象了两个 TaskExecuteException、TaskInitException异常,任务执行和任务初始化异常,方便捕获。
  • job目录中 抽象出 ApkJob 来管理所有的 Task 任务和 JobResult
  • output 目录 主要作用就是将输出的结果 以Json或者html格式的方式写入文件中
  • result 目录 对JobResult、TaskResult的抽象及相关实现
  • task 目录 所有任务的实现,包括 CountClassTask 统计类数量、MethodCountTask 统计方法量、UnzipTask 解压任务负责将apk解压成相关文件。
  • ApkChecker 负责创建Job,然后调用run方法。

类图

文字描述总显得有些乏力,画一下类结构图来帮助我们理解代码。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值