Android 增量编译-LayouCast的使用及修改

来源:互联网 发布:诺基亚商店软件下载 编辑:程序博客网 时间:2024/06/06 11:41

如需转载请注明地址:http://blog.csdn.net/rzleilei/article/details/52334878

LayoutCast是一个私人开源的,实现了android工程增量编译功能的工具。在此向原作者mmin18表示感谢。

一、源码实现流程以及原理

LayoutCast实现了类似于热修复的原理,主要分为电脑端和手机端部分:

手机端部分,需要在Application的onCreate方法中调用LayoutCast.init(this)注册。主要做了四个功能,按触发顺序介绍:

1.利用反射获取BaseDexClassLoader的pathList对象,然后把插入dex的Array赋值给这个对象。

2.注册activity的生命周期监听

3.在Application的onCreate方法中调用LayoutCast.init(this)注册。主要做了四个功能,插入dex, 注册activity的生命周期监听,重载Application的类加载器。

4.注册一个本地服务监听某个手机端口。

电脑端部分,当用户点击AS中的热部署按钮时,其实主要是执行了本地cash.py脚本,主要完成了下面的这些功能:

1.获取本地配置的变量,比如Android SDK目录,Java目录,工程目录,adb Path等等。(这一步有可能会因为本地配置路径不同发生异常,后面改进点之一

2.cash.sh由于文件是在工程目录下,所以可以通过相对路径获取到所有的Module的路径

3.扫描所有的module下的build文件夹,找到最新打包完成的一个apk为默认主工程,通过aapt工具解析apk获取到该package的报名

4.利用获取到的package包名和之前约定好的端口号,通过adb命令扫描手机端口,实现电脑端口和手机端口之间的映射,建立连接,同时获得对应的手机端口。

5.通过包名获取主工程目录,解析build.gradle,通过正则关键词dependence截取所有依赖的工程,然后扫描这些工程里面是否有修改文件,并记录(PS:这一步完全根据正则去提取是会有问题的,也是后面我们的修改点

6.判断打包时间和最晚修改时间,如果打包时间晚于最晚修改时间,则进程关闭,否则继续。

7.详细判断是src修改了还是res修改了,还是都改了。做对应的操作。

8.资源修改了,通过aapt工具打包。生成文件的路径在主工程/lcast下

9.java文件修改了,获取javac命令,定义list对象classpath,首先加入android_jar,然后找到工程依赖的所有jar包,都加入列表,包括maven依赖的。通过javac命令打包,生成class文件。通过dx工具打包生成dex文件。并通过网络传输到apk上。(这一步扫描依赖包的时候会缺少一个supprt-annotation-23.0.1.jar包

10.结束端口映射,任务结束。

二、改动点

我做的改动点主要就是上面介绍的红字描述的部分,改动的方式也很简单,那就是本地定义写死。

在loca.properties添加三个参数,如下

otherJarPath=E:\android\sdk\extras\android\m2repository\com\android\support\support-annotations\23.0.1\support-annotations-23.0.1.jarlayoutPath=CTMain,CTModule\CTSub1,CTModule\CTSub2aaptPath=E:\android\sdk\build-tools\21.1.2

分别代表本地的

otherJarPath:未扫描到的jar包的路径,用,区分。携程工程的话应该只缺少了supprt-annotation-23.0.1.jar包

layoutPath:需要扫描的的工程路径,写成相对于主工程的路径。同样用,区分。扫描越少的工程,则运行的速度就越快。

aaptPath:本地的aapt工具的路径。

cash.py文件中获取这几个路径的方法里面,我都改了成了从local文件中读取。

另外时间有限,暂时只修改了cash.py对java文件进行了支持,对res的支持的操作还未做

三、应用于具体工程

1、给Anroid Studio工具装一个插件IDEAPlugin.jar,下图所示。如果习惯用python命令执行的话,可以跳过这个步骤。


安装成功后重启Android Studio后,会多了一个这样的图标:


2、添加支持的jar包或者依赖的module

如果添加jar包的话,很简单,直接把library.jar包放到CTBusiness下的libs下。

如果依赖module的话,需要把library的工程导入到当前工程中。

修改android_2下的build.gradle文件,添加对library工程的支持,include ':library',如下:

        }    }    //Main entrance include 'CTMain' include ':library'}

修改CTBusiness下的build.gradle文件。添加下面中的最后一句。

dependencies {    compile fileTree(include: ['*.jar'], dir: 'libs')    FileTree jarfiles = fileTree(include: ['*.jar'], dir: '../../libs')// if (rootProject.hasProperty('buildID')) { //mcd打包不包含stetho jarfiles.exclude('stetho-*.jar')// } compile jarfiles compile 'com.android.support:multidex:1.0.0' compile 'com.android.support:support-v4:23.0.1' compile 'com.android.support:appcompat-v7:23.0.1' compile 'com.android.support:recyclerview-v7:23.0.1' apt 'org.greenrobot:eventbus-annotation-processor:3.0.1' compile ':Alipay_Lib:+@aar' compile ':BaiduWallet_Lib:+@aar' compile ':ReactAndroid:+@aar' compile project(':library')

3、对工程进行一些小改造。

首先、在CTApplication(自定义Application)的onCreate的方法中,添加一句LayoutCast.init(this)

其次、在CTMain中的Mainfest.xml中注册activity

<activity android:name="com.github.mmin18.layoutcast.ResetActivity" />

4.拷贝cash.py文件到android_2的主工程目录下

修改local.properties文件,添加对应的参数。下面是我的:

## This file is automatically generated by Android Studio.# Do not modify this file -- YOUR CHANGES WILL BE ERASED!## This file must *NOT* be checked into Version Control Systems,# as it contains information specific to your local configuration.## Location of the SDK. This is only used by Gradle.# For customization when using a Version Control System, please read the# header note.#Mon Aug 22 10:46:30 CST 2016sdk.dir=E\:\\android\\sdksolidMode=falseotherJarPath=E:\android\sdk\extras\android\m2repository\com\android\support\support-annotations\23.0.1\support-annotations-23.0.1.jarlayoutPath=CTMain,CTModule\CTSub1,CTModule\CTSub2aaptPath=E:\android\sdk\build-tools\21.1.2

四、忽略本地修改和提交

我们做了这么多的修改,如果不希望这些修改或新建文件提交到版本库当中,可以做如下的配置:

对于这些修改,分别两类。

对于Untracked files这些从未提交到版本库中的文件,可以忽略这些文件。修改android_2路径下.git/info/exclude文件。

添加下面的的内容,并保存,则会忽略掉这些新添加的文件,该操作只针对当前本地的git仓库。

library/

cast.py

对于modified这些已经被纳入到版本库的文件,可以本地不在对这些这些文件进行跟踪。

git update-index --assume-unchanged build.gradle//本地git仓库忽略对build.gradle文件的跟踪

git update-index –no-assume-unchanged build.gradle//恢复对build.gradle文件的关注

这些修改是对本地当前仓库生效的。

五、运行流程

运行前需要首先运行一遍工程。(由于只对java文件做了修改,res文件的修改还未做,所以暂时仅支持对java文件的动态编译)

然后修改java文件,保存。要确保修改的java文件在layoutPath标注的module下。点击一下蓝色的插件按钮就可以了。

如果未安装插件,则进入到android_2目录下,运行python cast.py命令。

六、缺陷以及同类对比

目前主流的动态编译框架有LayoutCast、facebook的Buck、google官方的install run、腾讯空间(未开源)、阿里聚宝刚刚开源的FreeLine。

原理上主要分为两类:

LayoutCast和Install Run都是基于类似于热修复原理的动态替换,把增量dex包插入到队列的最前端,这样确保修改后的.class文件会被编译。由于5.0以下版本具有dex检查,所以这两个方案只对5.0以上手机有效。

Buck基于的原理是多线程打包。apk打包是单线程,分为七步。而其实某些步骤是可以并行的,尤其javac编译这一步也是可以多线程并行的。Buck整理了相互依赖的拓扑图,采取了16线程同时打包,从而加快打包速度。

腾讯空间的话,同样是使用了热修复的原理,只不过在打包的时候,动态的添加进去一个dex包,其它所有包中的类都引用到这个dex包。从而绕过dex检查。

FreeLine刚刚开源,原理还没看,但是看介绍应该是融合了上面几家的优点的一个集合体。有空看看。

附件集合:

我修改后的cast.py文件以及local.properties、 IDEAPlugin.jar、lcast.jar

http://download.csdn.net/detail/aa5279aa/9614500

github:

https://github.com/aa5279aa/xt_LayoutCast

链接:

https://github.com/mmin18/LayoutCast

https://github.com/alibaba/freeline



PS:

如果问题,欢迎咨询。

文章为原创,原理是借助代码个人理解的,有可能有错误,也欢迎指出

0 0