Android编译速度如何才能加快

时间:2016-07-20 12:08:09    来源:信狮教育    已有人浏览
大家都关注: 深圳北大青鸟深圳信狮
分享到:
导读:写在前面的话对 于Android开发者而言,随着工程不断的壮大,Android项目的编译时间也逐渐变长,即便是有时候添加一行代码也需要等待好久才
写在前面的话
对 于Android开发者而言,随着工程不断的壮大,Android项目的编译时间也逐渐变长,即便是有时候添加一行代码也需要等待好久才能看见期待的效 果。之前加快Android编译的工具相对较少,其中最具有代表性的开源项目当属FaceBook的Buck和 mmin18的LayoutCast,除此之外还有JRebel 和 Jimulabs。不过前两天google宣布推出Instant Run加快Android 编译速度,相信对其他的工具来说都是一次冲击,这也是写这篇文章的动机。
 
相 对于Buck而言,LayoutCast显得更轻量一些,对项目的侵入性较弱。对于一些繁重的项目而言,Buck带来的好处是显而易见的,但是适配过程中 的坑也是很多的。Instant Run 对项目的侵入性其实也是比较大的,但是这些都不需要用户去操作、配置,所以看起来和LayoutCast一样属于轻量型的。
 
时间去哪儿了?
 
 
Android程序编译大致过程如图所示,详细的过程可以参考gradle 中的tasks。
 
 
那么为什么我们每次编译都需要等待那么久?事实上我们我们可以gradle中添加TaskExecutionListener来监听gradle脚本中每个task的执行时间。
 
执行脚本可以发现主要的费时在dex(包含preDex)以及install这两个步骤。BUCK和LayoutCast的主要工作也是集中于这些费时的步骤上面。
 
如何加快?
 
 
开发过程中对项目的改动一般分为Java文件的修改以及资源文件的修改,这些修改都会涉及到上述的几个费时步骤,这也就是为什么即便我们修改一行代码也需要编译很久。
 
1、Java文件修改
 
通常,修改的.java文件会先经过javac操作生成.class文件。而后与其他的.class文件经过dx生成.dex文件。经过dx的操作很费时,针对这种情况,BUCK、LayoutCast和Instant Run采用了两种方法来解决。
 
BUCK
 
BUCK建立了一套完善的依赖规则以及细化的缓存系统来缩减编译时间,并通过使用三方的dex merege工具将.dex文件合并的时间复杂度从O(N^2)降到O(NlgN)。
 
如图所示,当修改A.java文件时,只涉及到相应的dx操作以及dex merge操作(红色部分),这样就大大的缩减了dx的操作时间。BUCK在依赖规则上狠下功夫推出了ABI,更是进一步的减少了不必要的操作。
 
LayoutCast
 
LayoutCast的实现同很多插件的实现原理差不多,具体分析如下:
 
在ClassLoader查找类的时候会先去调用BaseDexClassLoader类中的findClass方法。
 
 
随后在DexPathList类中根据dexElements来查找相应的class。
 
 
其中dexElements代表着不同dex文件。
 
 
也就是说,在ClassLoader加载类的时候会去按照dexElements中dex文件的顺序依次查找,如下图所示,在1.dex中查找到了A类,那么就不会再从后面的dex文件中继续查找了。
 LayoutCast就是利用这样的原理,将修改的Java文件生成dex文件,并将此dex文件利用反射的方式插入到dexElements数组的前面。当然,从Java到dex的过程需要额外的查找各种依赖包之类的工作,这部分工作在cast.py中实现。
 
这种方式的实现在ART下是没有问题的,但是在Dalvik中就会出现IllegalAccessError的问题
 
 
Install Run
 
Install Run 同样也是生成新的增量dex,但是新增dex中的类和原来的类名有区别。比如说,在修改Hello.java类之后,会生成包含Hello$overide类的dex文件。
 
那么,这个新增的dex文件中Hello$Override类是如何被调用的?
 
我们先看看原来的Hello.java文件经过Instant Run 编译前后的区别:
 
编译前的hello.java文件
 
 
经过Instant Run之后的
 
 
可以看出,如果$change存在的话,就会调用$change中相应的函数,那么我们只需要通过反射将Hello.java中$change字段改为修改后的Hello$override的类就Ok了。
 
这也就是为什么Instant Run并不存在前面说到的IllegalAccessError的问题,并且支持不重启就能看见修改效果的原因。
 
2、Res修改
 
Resource 文件的修改会涉及到AAPT、ApkBuilder以及最后的Install操作。其中APPT的操作要求比较高,LayoutCast、Instant Run均没有在这部分进行优化,他们的主要工作在于后面的两个操作。其主要的思路在于将修改的后的资源利用aapt打包成新的.ap_文件,并通过反射的 方式将原来的资源文件改为修改后的。
 
LayoutCast
 
LayoutCast主要做了两件事。
修改LayoutInflater服务
对于下面的用法我们并不陌生:
 
 
其中LayoutInflater.from的实现是在Context的实现类ContextImp中获取LAYOUT_INFLATER_SERVICE系统服务
 
 
那么ContextImpl又是如何获取相应的服务的,查看ContextImpl类可以发现,
 
 
可 以发现调用getSystemService的过程是在SYSTEM_SERVICE_MAP的表中查找ServiceFetcher,并返回 ServiceFetcher中的mCachedInstance。那么只需要将mCachedInstance替换为自定义的BootInflater 并在BootInflater中完成Resource的Overrirde就可以了,如下图所示。
 
 
修改Resource
 
我们知道Activity中的通过调用getResources()方法来访问资源,这实际上是调用ContextWrapper类中的getResource()方法
 
 
LayoutCast中就采用替换mBase为自定义的OverrideContext,并在其中将Resource返回为修改后的Resource。
 
Instant Run
 
Instant Run 对资源文件的处理和LayoutCast基本类似,但是在细节的处理上有所不同,比如Instant Run 通过对ActivityThread类中的mPackages和mResourcePackages的修改来改变LoadedApk中mResDir的 值。
 
 
资源文件修改的处理相对于Java文件的处理较为复杂,这中间涉及到aapt、attribute唯一性 、ID值一致等问题都增加了资源文件处理的难度。
 
总结
 
总的来说
 
 
每 种方法都有自己的特色,BUCK依赖于自己强大的缓存和依赖管理系统。而LayoutCast和Instant Run相对而言采用了更灵巧的方法。相对而言,Instant Run 凭借着天然的优势(和升级后的gradle结合),可以胜LayoutCast一筹,但是LayoutCast这种想法的提出还是很赞的。目前增量的编译 集中在Java文件的修改,对于Res的修改暂时好像还不支持,这在后续应该会有提升吧。
  • 人生无处不套路,比如就业面试,大家可能就中了不少HR的套路,有时候一天面试好几家公司,自我感觉良好,HR总是叫你回家等消息,可是左等右

  •   在电脑技术兴盛的今天,JAVA语言得到了最广泛的应用,从网站建设、电子商务、游戏开发、移动互联网等,JAVA语言技术在其中所站的开发份

  •   对于高中毕业生来说,刚刚走出校园大门,学历不高且没有工作经验,想找份赚钱多的工作,该怎么做呢?2017年高中毕业不上大学,学什么专业

  • 怎么成为一个软件开发者?电脑编程技术为何让90后宅男疯迷?软件开发电脑编程技术成90后高薪就业技术。我们知道如今软件工程师非常抢手,尤

  • 作为职业教育学校,在人才培养上,不只是进行简单的教学,更应侧重学生的动手实践、创新发展。尤其在新时代,企业对人才的要求更高。北大青

  •   随着软件测试行业的逐渐发展,性能测试也变得火热起来。从各大测试论坛和测试交流群的交流主题的热门程度来看,性能测试已经成为大家非

  • 随着电子时代的来临,电脑早已成为人们生活、学习、工作、娱乐不可或缺的工具。电脑办公、手机上网、聊天娱乐、网上购物、用网银办理各种付

  •       就业作为一个老生常谈的问题,已经不算新鲜,但是每一年还是在毕业季大量毕业生涌入人才市场寻找工作时成为一时热门话题。人们

  • 深圳有什么好的JAVA培训学校?教JAVA 技术的机构有很多,如何知道这些培训学校好不好呢?我们先来分析下,目前IT行业比较突出的问题是实战型精英人才的缺乏,面对琳琅满目的JAVA培训学校

  • 安卓开发新手容易陷入的误区都有哪些?Android平台是一个新手最广为人知的平台。它不仅是一个廉价的工具,而且有着良好的开发社区,以及从

  • 陈*东:梦想照进现实,奋力前行

    姓名:陈*东班级:JT29班学历:大专年龄:23就业企业:云奥贸易就业岗位:开发工程师就业薪资:8000我,曾是一个刚离开校园的毕业生,怀揣

  • 李*同学:一技在身,实现人生的翻转

    中专毕业后,追求发展的我,便在各个行业中辗转,发现社会上、生活中太多残酷的现实,远没以前上学那会儿想得那么理想。我学历不高、没有一技之长,生存都有些不容易,更别谈发展。出

  • 陈*喜:很庆幸我选择的是北大青鸟

    高中毕业后我就想着学个技术,很庆幸我选择的是深圳信狮学校学软件工程师技术。感谢老师对我的支持与鼓励,以及长期以来的帮助,让我在信狮学校度过了一段非常充实而有意义的学习生活

  • 石柱:走好每一步,干好每一件事情

    姓名:石柱年龄:19岁学历:大专就职企业:深圳市网合科技有限公司就职岗位:Java软件工程师就业薪资:4000元公司简介:深圳市网合科技股份

  • 万*:青春,就是用来奔跑的

    来信狮前,我的情况是高中毕业,IT技能零基础,在工厂做了3年普工,拿着每月的血汗钱工资,听着周边同事的各种抱怨、各种对生活的失望、或

热点专题 更多 >
热门标签 更多 >