22讲包体积优化上如何减少安装包大小_第1页
22讲包体积优化上如何减少安装包大小_第2页
22讲包体积优化上如何减少安装包大小_第3页
22讲包体积优化上如何减少安装包大小_第4页
22讲包体积优化上如何减少安装包大小_第5页
已阅读5页,还剩9页未读 继续免费阅读

付费下载

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、22讲包体积优化(上):如何减少安装包曾经在 5年的时候,我在WeMob eDev就写过篇章Andro d安装包相关知识汇总也开源了个不少同学都使过的资源具AndResGuard。现在再看看这篇4年前的章,就像看到了4年前的,感触颇多啊。年过去了,上随意搜都有量安装包优化的章,那还有哪些“深”的珍藏秘笈值得呢?时今,包体积也从当年的30MB增到现在的100MB了。经常会想,现在W F 这么普遍了,且5G都要来了,包体积优化究竟还有没有意义?它对户和应的价值在哪?安装包的背景知识还记得在2G时代,每个只有30MB流量,那个时候安装包体积确实关重要。当时我在做“搜狗输法”的时候,就严格要求包体积在

2、5MB以内。年过去了,对包体积的看法改变吗?1. 为什么要优化包体积在2018年的Goog e I/O,Goog e透露了Goog e P ay上安装包体积与转化率的关系图。从这上看,体来说,安装包越,转化率越这个结论依然成。包体积对应的影响,主要有下点:转化率。个 00MB的应,户即使点了,也可能因为络速度慢、突然反悔失败。对于个10MB的应,户点了之后,在犹豫要不要下的时候已经 载完了。但是正如上图的数据,安装包与转化率的关系是常微妙的。10MB跟15MB可能差距不,但是10MB跟40MB的差距还是常明显的。推成本。般来说,包体积对推和商预装的单价会有常的影响。特别是商预装,这主要是因 商

3、留给预装应的总空间是有限的。如果你的包体积常 那就会影响商预装其他应。应市场。苹果的App Sto e强制超过150MB的应只能使W F 络Goog e P ay要 超过100MB的应只能使APK扩展件式上传,由此可应包体积对应市场的服务器带宽成本还是会有点压的。前成超级App越来越多,很多产品也希望成为下个超级App,希望功能可以万象,满户的切需求。但这同样也导致安装包不断变,其实很多户只使到很少部分功能。下就来看看、付宝以及淘宝这款超级App这年安装包增的情况。我还记得在15年的时候,为了让6.2版本于30MB,我使了各种各样的段,把体积从34MB降到29.85MB,资源具AndResGu

4、ard也就是在那个优化专项中写的。年过去了,包体积已经涨到100MB了,淘宝似乎也不容乐观。相之下,和付宝相对还较节制。2. 包体积与应性能React Nat ve 5MB、F utter 4MB、浏览器内核20MB、Chrom um络库2MB现在第三开发框架和扩展库越来越多,很多的应包 积都已经是MB起步 。那包体积除了转化率的影响,它对应性能还有哪些影响呢?安装时间。件拷 、L brary解压、编译ODEX、签名校验,特别对于Andro d 5.0和6.0系统来说(Andro d 7.0之后有了混合编译),13个Dex光是编译ODEX的时间可能就要5分钟。运内存。在内存 化的时候就Re o

5、u ce资源 L b a y以及Dex类加载这些都会占不少的内存。ROM空间。100MB的安装包,启动解压之后很有可能就超过200MB了。对机户来说,也会有很的压。在“I/O优化”中过,如果闪存空间不,常容易出现写放的情况。对于部分两年前的“千元机”,淘宝和时候,性能往往就被排到后。都已经玩不转了。“技术短期内被估,期会被低估”,特别在业务速发展的包体积对技术员来说应该是常重要的技术指标,不能放任它的增,它对还有不少意义。业务梳理。删除或者低价值的业务,都是最有效的性能优化式。需要经常回顾过去的业务,不能只顾着往前冲 适时地还“技术”。开发模式升级。如果所有的功能都不能移除,那可能需要开发模式

6、的转变,地采程序 H5这样开发模式。包体积优化国内地开发者都常羡慕海外的应,因为海外有统的Goog e P ay市场。它可以根据户的ABI、dens ty和anguage发布,还有在2018年推出的App Bund e。事实上安装包中就是Dex、Resource、Assets、L brary以及签名信息这五部分,接下来就来看看对于国内应来说,还级“秘籍”。1. 代码对于部分应来说,Dex都是包体积中的头。看下上表格中、付宝和淘宝的数据,它们的Dex数量从1个增到10多个,的代码量真的增了那么多倍吗?且Dex的数量对户安装时间也是个常的,在不砍功能的前提下,看看有哪些法可以减少这部分空间。Pro

7、Guard“个ProGuard配置九个坑”,特别是各种第三SDK。 keep的现象。需要仔细检查最终合并的ProGuard配置件,是不是存在过度你可以通过下的法输出ProGuard的最终配置,尤其需要注意各种的keep *,很多情况下某个法,或者是类名就可以了。只需要keep其中的某个包、-prconfiguration configuration.txt那还有没有哪些法可以进步加度呢?这时可能要向四组件和V ew下了。般来说,应都会keep住四组件以及V ew的部分法,这样是为了在代码以及XML布局中可以引到它们。事实上完全可以把exported的四组件以及V ew,但是需要完成下个作:XM

8、L替换。在代码之后,需要同时修改Andro dMan fest以及资源XML中引的名称。代码替换。需要遍历其他已经好的代码,将变量或者法体中定义的字符串也同时修改。需要注意的是,代码中不能出现经过运算得到的类名,这种情况会导致替换失败代码替换的法,我使ASM。不熟悉ASM的同学也不着急,后我会专讲它的原理和法。饿了么曾经开源过个可以实现四组件和V ew的组件Mess,不过经没在了,可供你参考。Andro d Stud o 3.0推出了新Dex编译器D8与新具R8,前D8已经正式Re ease,约可以减少3%的Dex体积。但是计划于取代ProGuard的R8依然处于阶段,期待它在未来能有更好的表

9、现去掉Debug信息或者去掉号某个应通过相同的ProGuard规则成个Debug包和Re ease包,其中Debug包的是4MB,Re ease包只有3.5MB。既然它们ProGuard的与优化的规则是样的,那它们之间的差异在哪呢?那就是DebugItem。/ 情况 :变量public String activityName = com.sle.TestActivity;/ 情况:法体startActivity(newent(this, com.sle.TestActivity);/ 情况三:通过运算得到,不持startActivity(newent(this, com.sle + .Test

10、Activity);-keep public class * extends android.app.Activity-keep public class * extends android.app.Application-keep public class * extends android.app.Service-keep public class * extends android.content.BroadcastReceiver-keep public class * extends android.content.ContentProvider-keep public class

11、* extends android.view.ViewDebugItem主要包含两种信息:调试的信息。函数的参数变量和所有的局部变量。排查问题的信息。所有的指令集号和源件号的对应关系。事实上,在ProGuard配置中般也会通过下的式保留号信息。对 去除debug nfo以及号信息更详细的 析你认真看 下付宝的 篇章And o d包极致压缩。通过这个法,可以实现既保留号,但是可以减少 5%的Dex体积。事实上,付宝参考的是的个开源编译具ReDex。ReDex除了没有档之外,绝对是客户端领域常硬核的个开源库 常值得你去认真研究。ReDex这个库的好东实在是太多了,后还会反复讲到,其中去除Debug

12、信息是通过Str pDebugInfoPass完成。-keepattributes SourceFile, LineNumberTableDex分包当在Andro d Stud o查看个APK的时候,不知道你是否知道下图中“denes 19272 methods”和“referen40229methods”的区别。关于Dex的格式以及各个字段的定义,你可以参考Dex件格式详解。为了加 对Dex格式的理解,010Ed tor。你使redex : passes : StripDebugInfoPass,StripDebugInfoPass : drop all dbg info : 0,/ 去除所

13、有的debug信息,0表示不去除 drop local variables : 1, / 去除所有局部变量,1表示去除 drop line numbers : 0,/ 去除号,0表示不去除drop src files : 0,use whiist : 0, drop prologue end : 1,droplogue begin : 1,drop all dbg info if empty : 1“dene c asses and methods”是指真正在这个Dex中定义的类以及它们的法。“reference methods”指的是dene methods以及dene method 引到的

14、法。简单来说,如下图所示如果将C ass A与C ass B分别编译到不同的Dex中,由于method a调了method b,所以在c asses2.dex中也需要加上method b的d。因为跨Dex调造成的这些冗余信息,它对Dex的会造成哪些影响呢?method id爆表都知道每个Dex的method d需要 65536 因为method d的量冗 导致每个Dex真正可以放的C ass变少,这是造成最终编译的Dex数量增多。信息冗余。因为我 需要跨Dex调的法的详细信息,所以在c asses2.dex还需要C ass B以及method b的定义 造成 t ng dtype dp oto

15、 d 这部 信息的冗 。事实上,我定义了个Dex信息有效率的指标,希望保证Dex有效率应该在80%以上。同时,为了进步减少Dex的数量,希望每个Dex的法数都是满的,即分配了65536个法。那如何实现Dex信息有效率呢?关键在于需要将有调关系的类和法分配到同个Dex中,即减少跨Dex的调的不太可能可以计算出最优解,只能得到局部的最优解。情况。但是由于类的调关系常复杂,为了提Dex信息有效率,我在时曾参与写过个依赖分析的具Bu der。但在的7.0版本,你可以看到上表Dex信息有效率 = define methods数量/reference methods数量中Dex的数量和都增了很多,这是因为

16、他们不把这个具搞失效了。Dex数量的增多,对于Tinker热修复时间、户安装时间都有很影响。如果把这个问题修复,10MB左右。7.0版本的Dex数量应该可以从13个降到6个左右,包体积可以减少但是我在研究ReDex的时候,发现它也提供了这个优化,且实现得是贪算法计算局部最优值,具体算法可查看CrossDexDefM n m zer的更好。ReDex在分析类调关系后,使的为什么不能计算到最优解?因为需要在编译速度和效果之间找个平衡点,在ReDex中使这个优化的配置如下:那么通过Dex分包可以对包体积优化多少呢?因为Andro d默认的分包式做得实在不好,如果你的应有4个以上的Dex,我相信这个优

17、化少有10%的效果。Dex压缩我曾经在逆向的App时惊奇地发现,它怎么可能只有个700多KB的Dex。Goog e P ay是不允许动态下发代码的,那它的代码都放到哪 呢事实上App的c asses.dex只是个壳,真正的代码都放到assets下。它们把所有的Dex都合并成同个secondary.dex.jar.xzs件,并通过XZ压缩。redex : passes : erDexPass,erDexPass : minimize cross dex refs: true,minimize cross dex refs method ref weight: 100, minimize cros

18、s dex refs field ref weight: 90, minimize cross dex refs type ref weight: 100, minimize cross dex refs string ref weight: 90XZ压缩算法和7-Z p样,使的都是LZMA算法。对于Dex格式来说,XZ的压缩率可以Z p30%左右。但是不知道你有没有注意到,这套案似乎存在些问题:次启动解压。应次启动的时候,需要将secondary.dex.jar.xzs解压缩,根据上图的配置信息,应该共有11个Dex。使多线程解压的式,这个耗时在端机是百毫秒左右,在Zstandard或者Br

19、otli呢?主要是压缩率与解压速度的权衡。机可能需要35秒。这为什么不采ODEX件成。前我就讲过,当Dex常多的时候会增加应的安装时间。对于的这个做法,次成ODEX的时间可能就会达到分钟级别。为了解决这个问题,使了ReDex另外个超级硬核的法,那就是oatmea 。oatmea 的原理常简单,就是根据ODEX件的格式,成个ODEX件。它成的结果跟解释执的ODEX样,内部是没有机器码的。如上图所示 对常的流程需要fo k进程来成dex2oat 这个耗时 般都较。通过oatmea直接在本进程成ODEX件。个10MB的Dex,如果在Andro d 5.0成个ODEX的耗时10秒以上,在Andro d

20、 8.0使speed模式1秒左右,通过oatmea 这个耗时100毫秒左右。我 直都很想把oatmea 引进T nke分版本适配的。但是较担兼容性。因为每个版本ODEX格式都有 些差异 oatmea 是需要2. Native Library现在、美颜、AI、VR这些功能在应越来越普遍,但这些库般都是使C或者C+写的,也就是说,的APK中Nat ve L brary的体积越来越了。对于Nat ve L brary,传统的优化法可能就是去除Debug信息、使c+ shared这些。那还有没有更好的优化法呢?Library压缩跟Dex压缩样,L brary优化最有效果的法也是使XZ或者7-Z p压缩

21、。在默认的 b录只需要加载少数启动过程相关的L b a y 其他的L b a y都在次启动时解压。对 L b a y格式来说,压缩率同样可以Z p30%左右,效果分惊。有个So加载的开源库SoLoader 它可以跟这套案配合使。和Dex压缩样,压缩案的主要缺点在于次启动的时间,毕竟对于机来说,多线程的意义并不,因此要在包体积和户体验之间做好平衡。Library合并与裁剪对于Nat ve L brary,都隐藏在源码中。中的编译构建具Buck也有 个较硬核的科技 当然在官档中是完全找不到的,它们Library合并。在Andro d 4.3之前,进程加载的L brary数量是有限制的 在编译过程,

22、个。具体思路你可以参考章Andro d nat ve brary merg ng以及Demo。可 动将部分L brary合并成Library裁剪。Buck有个 e nker的功能 原理就是分析代码中JNI法以及不同L brary的法调,找到没有的导出symbo ,将它们删掉。这样linker在编译的时候也会把对应的代码同时删掉,这个法相当于实现了L brary的 ProGuard Shr nk ng功能。包体积关于包体积,如果直放任不管,个版本之后就会给你很的“惊喜”。我了解到些应对包体积卡得很紧,任何超过100KB的功能都需要。对 包 积的通常有下种。这个常好理解,每个版本跟上个版本包体积的对情况。如果某个版本体积增过,需要分析具体原因,是否有优化空 。依赖。每版本都需要依赖,这包括新增JAR以及AAR依赖。这是因为很多开发者常不细,经常会不把些超的开源库引进来。规则。如果发现某个版本包体积增很,需要分析原因。规则也就是将包体积的抽象为规则,例如资源、件、重复件、R件等。如我在的时候,使ApkChecker实现包体积的规则包体积的最好可以实现动化与化,作为发布流程的其中个环节。不然通过的式,很难持续坚持下去。总结今天我 起分析了实现难度较的包体积优化法,可能有会想这些法实现难度那么,真的有价值吗?根据理解,现

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

最新文档

评论

0/150

提交评论