Gradle 构建:从入门到实战
ColletteChu
8年前
<p style="text-align:center"><img src="https://simg.open-open.com/show/2f00b461c836da92b158dd97325ba6ce.jpg"></p> <h3>前言</h3> <p>本文章主要针对Gradle讲解,从入门到实战(Android Studio),让你快速上手Gradle。</p> <p><strong>一、什么是构建工具? </strong></p> <p>一个可编程的工具,能够以可执行和有序的任务来表达满足需要的自动化过程。</p> <p>以Java为例,要得到一个简单可运行的Jar文件,需要下面几步:</p> <ol> <li> <p>编译源代码</p> </li> <li> <p>运行测试(前提是你有测试)</p> </li> <li> <p>拷贝Class文件到目标目录</p> </li> <li> <p>打包Class文件为Jar文件</p> </li> </ol> <p>这是一个完整的可自动化的过程,在没有构建工具之前,是由谁来做?IDE。一个强大的IDE,以上的步骤都只需要按几个按钮,这让开发人员的生活变得很美好,完全集中在写出优秀的代码。</p> <h3><strong>二、Java世界的构建工具</strong></h3> <p>在Java的世界里,目前在被使用的常用构建工具有三个:Ant,Maven,Gradle。</p> <p>Ant的核心是由Java编写,采用XML作为构建脚本,这样就允许你在任何环境下,运行构建。Ant基于任务链思想,任务之间定义依赖,形成先后顺序。缺点是使用XML定义构建脚本,导致脚本臃肿,Ant自身没有为项目构建提供指导,导致每个build脚本都不一样,开发人员对于每个项目都需要去熟悉脚本内容,没有提供在Ant生态环境内的依赖管理工具。</p> <p>Maven团队意识到Ant的缺陷,采用标准的项目布局,和统一的生命周期,采用约定由于配置的思想,减少构建脚本需要的编写内容,活跃的社区,可以方便找到合适的插件,强大的依赖管理工具。缺点是采用默认的结构和生命周期,太过限制,编写插件扩展麻烦,XML作为构建脚本。</p> <p>如果有一个构建工具可以折中,同时拥有Ant和Maven的优点,是不是很爽?告诉你有,那就是Gradle。</p> <h3><strong>三、Gradle 构建</strong></h3> <p>Gradle是一个基于Apache Ant和Apache Maven概念的项目自动化建构工具。它使用一种基于Groovy的特定领域语言来声明项目设置,而不是传统的XML。</p> <p>1、Gradle-Wrapper</p> <p>Gradle可以在没有安装Gradle的情况下使用,这时候就需要Gradle Wrapper了。Gradle Wrapper其实就是一个脚本文件,它会在没有安装Gradle的情况下为我们下载Gradle,之后我们就可以使用gradlew命令,像使用gradle一样来使用Gradle了。</p> <p>创建项目完毕之后,会发现我们的项目中有如下一些文件:</p> <p>gradlew (Unix Shell 脚本)</p> <p>gradlew.bat (Windows批处理文件)</p> <p>gradle/wrapper/gradle-wrapper.jar (Wrapper JAR文件)</p> <p>gradle/wrapper/gradle-wrapper.properties (Wrapper属性文件)</p> <p>我们就可以像使用gradle命令一样使用gradlew了。Gradle Wrapper会自动为我们下载合适的Gradle版本。默认情况下,下载位置是$USER_HOME/.gradle/wrapper/dists,如果设置了GRADLE_USER_HOME环境变量,那么就会下载到GRADLE_USER_HOME/wrapper/dists下。</p> <p style="text-align:center"><img src="https://simg.open-open.com/show/822074bbfc89c282cc25fa69ae728758.jpg"></p> <p>上面是gradle-wrapper.properties文件中的内容,可以直接编辑文件修改Wrapper的版本,或者使用</p> <p>gradle wrapper --gradle-version 3.2.1来设置Wrapper的版本</p> <p>2、 build的生命周期</p> <p>Gradle的构建脚本生命周期具备三大步,如下:</p> <p style="text-align:center"><img src="https://simg.open-open.com/show/b27d88ed2b4008ab28aedb1184c0249a.jpg"></p> <p>可以看见,生命周期其实和上面构建脚本Build script的执行流程是可以关联上的。(上面关于Task方面的内容本文中不会使用。)</p> <p>3、设置脚本Settings script</p> <p>在对工程进行配置(譬如多项目树构建)时Settings实例与settings.gradle文件一一对应,它用来进行一些项目设置的配置。这个文件一般放置在工程的根目录。譬如:</p> <p style="text-align:center"><img src="https://simg.open-open.com/show/ecdd9c6c599afb0d29c757af75b6c4c3.jpg"></p> <p>多模块项目,就是在settings.build 中添加模块名称。 例如:</p> <p style="text-align:center"><img src="https://simg.open-open.com/show/cdde5a1df6aa117f0d6c3b532a8485eb.png"></p> <p>4、顶层build.gradle文件</p> <p style="text-align:center"><img src="https://simg.open-open.com/show/b3b32163f6b70c94ff3edc14ce514863.jpg"></p> <p>构建的时候默认会配置上一个JCenter() 仓库,也可以加上其他的仓库,比如,BRVAH这个第三方框架,就没有放在JCenter里面,因为这个仓库发布的流程比较复杂,时间也比较久,所以就发布在https://jitpack.io 仓库上,所以在使用BRVAH的时候就要在allprojects 中添加jitpack仓库地址。</p> <p><strong>进入实战</strong></p> <p>1.BuildConfig和资源</p> <p>通过配置灵活切换不同环境的 接口地址</p> <p>相信用eclipse开发的时候我们都是用的以下这种方法来切换接口地址的:</p> <p style="text-align:center"><img src="https://simg.open-open.com/show/f038a6082581abefc77b5b1eb9458b82.jpg"></p> <p>这种写法应该都不陌生,那在Gradle构建中,有没有可能用更好的方法来解决这个问题咧?</p> <p>答案是有可能的!</p> <p>自SDK工具版本升级到17之后,构建工具都会生成一个叫作BuildConfig的类,该类包含一个按照构建类型设置值的DEBUG常量,可以定义其他的一些属性,Gradle提供了一个buildConfigField 方法 ,下面就是顶一个String类型的BASE_URL常量,值为"http://debug.example.com/api”。</p> <p style="text-align:center"><img src="https://simg.open-open.com/show/4abcd33356bb77b8fb00b4ba24736dc2.jpg"></p> <p>这里要注意的是添加String类型的数据的时候要添加转义的引号,不然是创建不成功的,例如:</p> <p style="text-align:center"><img src="https://simg.open-open.com/show/233d5aca21657af3719a062a7ed226b7.jpg"></p> <p>在这里还有一个问题,如果开发的是一个多模块项目,那么在library中定义这种属性,默认是不区分debug和release版本的。缺省情况下,无论你选用什么Build variant ,库工程都只会打出release包,这是由于Gralde语言的限制造成的,但如果想强制使用debug,可以如下指定:</p> <p style="text-align:center"><img src="https://simg.open-open.com/show/da7b177aaa6f21302025c1cbfb92d160.jpg"></p> <p><strong>2. Gradle修改资源文件信息</strong></p> <p>配置不同环境的资源文件</p> <p>同样的Gradle也提供了一个resValue() 方法,下面就是定义了一个app_name的string资源。</p> <p style="text-align:center"><img src="https://simg.open-open.com/show/1f40c675c6d461b361c67f8aef62d942.jpg"></p> <p>但是上面这种定义是错误的,build的时候会报以下这种错误:</p> <p>提示定义了重复的资源,所以在用resValue()的时候不要在.xml文件定义相同名字的资源数据。</p> <p>3.gradle.properties 文件</p> <p>解决频繁同步问题</p> <p>相信大家在尝试上面的方法的时候有这样一个问题,那就是我们每修改一下.gradle文件,AS工具就提示要”Sync Now”,这样是不是有点麻烦了咧? 下面就可以用到gradle.properties文件来进一步的优化。</p> <p style="text-align:center"><img src="https://simg.open-open.com/show/00d7e3517f278e2c5911489a165eda6b.jpg"></p> <p>4.Gradle配置生成apk文件名</p> <p>防止release覆盖问题,便于保存历史release记录</p> <p style="text-align:center"><img src="https://simg.open-open.com/show/f93349ae886c1db87afb9c81cef8cf5f.jpg"></p> <h3>参考资料:</h3> <p>http://blog.csdn.net/yanbober/article/details/49314255</p> <p>http://benweizhu.github.io/blog/2015/01/31/deep-into-gradle-in-action-1/</p> <p>http://blog.csdn.net/u011054333/article/details/53999590</p> <p>http://blog.csdn.net/xude1985/article/details/51548245</p> <p> </p> <p> </p> <p>来自:http://mp.weixin.qq.com/s?__biz=MzIwMzYwMTk1NA==&mid=2247483668&idx=1&sn=ff2612a607378053cbe8476e94af5a4f&chksm=96cda059a1ba294f715cc3b126541127bee9da877c7f2ad982e82c85f5e35e6a21a5934994d7&mpshare=1&scene=23&srcid=022076xydDBBtAMqcWko1Du1#rd</p> <p> </p>