GRADLE 构建最佳实践
随着谷歌对Eclipse的无情抛弃和对Android Studio的日趋完善,使用gradle构建Android项目已经成为开发者的一项必会良技。那么,问题来了,采用什么样的姿势才能让项目开发构建过程高潮迭起,精彩不断呢?
其实网上有很多关于gradle的文章,gradle官方和谷歌也提供了详细的文档和教程,可素,当你在构建过程中遇到一些问题或者有特殊的爱好(需求)的时候,这些东西未必能帮(mei)上(shen)什(me)么(niao)忙(yong),然后就是一顿FQ找谷歌蜀黍约约约,去stackoverflow上各种搜刮问大神,最后解决了。即使没有真的解决那么就忍了。
那怎么行?是可忍孰不可忍,奇技淫巧必须有。所以就会有这样一篇文章,我在这里不讲原理,因为我知道很多人明白辣么多的底层原理,仍然撸不上好代码,做不成好项目,出不了好产品,自然也就过不好这一生咯。
我们先从GRADLE构建的时间花销开始谈起。
加速篇
GRADLE的构建过程通常会比较漫长,一个中等项目,10M左右大小的app,一次完整构建大概在5分钟左右,是不是很吓人,当然,如果是在调试阶段,采用Android Studuo 2.0,默认提供的Instant Run方式,每次修改都不会重新构建项目,从而加快了构建过程。恩,这是另一个故事,这里,我们先谈谈GRADLE脚本的加速姿势。
一般来说,GRADLE一次完整的构建过程通常分成三个部分,初始化,配置和执行任务,那么我们可以考虑从这三个部分分别尝试优化。
使用daemon
构建初始化的很多工作是关于java虚拟机的启动,加载虚拟机环境,加载class文件等,如果这些动作交给一个单独的后台进程去做,那么,第一次初始化之后的修改代码再构建是不是可以节省很多时间呢?答案是肯定的,通过在gradle.properties加入这样一句来开启,如果想让修改全局所有项目都生效,那么修改这个文件~/.gradle/gradle.properties
按需配置
配置有一种方式是按需配置,目前还在试验孵化阶段,所以默认是关闭的,可以通过在gradle.properties加入这样一句来开启
依赖库使用固定版本
项目开发过程中,难免需要用到三方库,这就形成了项目之间的依赖关系,GRADLE提供了多种集成三方库的方式,提供了很方便的项目依赖管理,本地库,库工程,maven库全支持。既然用到库,就会遇到库版本的问题和升级问题,其中maven库的依赖管理支持一种动态版本的方式,也就是说,GRADLE可以做到不依赖具体某个版本的库,而是每次从repo拉取最新的库到本地做编译。具体使用是这样的:
拿gson库举例,如果依赖2.2.1这个版本,可以在build.gradle文件里这样写
如果不想依赖具体的库,想每次从maven repo中拉取最新的库,那么,可以写成这样:
也可以写成这样
甚至可以这样
其中含义相信不用我解释,大家也看得明白吧。
用”+”来通配一个版本族,这样有个好处是maven上有新库了,不用你操心升级,GRADLE编译的时候自动升级了,但是带来了两个坏处,一是,有可能新版库的接口改了,导致编译失败,这个时候需要修改代码做升级适配;更大的坏处是,每次GRADLE编译完整的项目,都会去maven上试图拉取最新的库,这样,拖慢了编译速度,尤其在网络非常差的时候,所以,为了构建速度,建议写死依赖库的版本号。
升级到最新的GRADLE和JDK
有一个很通俗的道理是,发展的东西会越来越好,最新版的GRADLE和JDK往往是性能最好,运行最流畅最快的,所以,升级吧,JDK的升级这里不说了,具体看Oracle的官方文档。这里说说GRADLE的版本升级,GRALDE采用了一种叫做wrapper的方式,可以做到每个项目独立使用其自己的GRADLE版本,这样做的好处不言而喻,每个项目的构建环境独立,互不影响。但为什么会出现这个东西,我的猜想是因为GRADLE发展太快,新旧版本之间很难兼容。如果你有多个项目都采用GRADLE构建,假设都用同一个全局的GRADLE,那么当这个GRADLE升级后,所有的项目可能都会编译失败,你得一个一个改配置,那么,下次再升级,同样的流程的再走一遍,是不是很烦。采用wrapper的方式很好的解决了这个问题,每个项目采用独立的GRADLE版本,互不影响,如果你只想升级其中一个,你改这一个项目的GRADLE wrapper就好了。在你的项目目录下找到这个文件gradle/wrapper/gradle-wrapper.properties并修改distributionUrl=https\://services.gradle.org/distributions/gradle-2.11-all.zip到你想升级的版本就可以了。
减少编译脚本中的I/O操作
有时候,编译脚本中会有一些代码做动态信息的获取,比如想从git中获取一个数字作为版本号
其实这个操作主要是为了在构建的机器上为了发布版本而做的,日常环境研发调试无需这样,所以可以优化成如下方式:
并行构建模块化项目
将你的项目拆分成多个子项目并开启并行构建也是一个不错的主意,比如将相对独立的模块拆分成独立的库工程(Library projects),主工程(Application project)依赖这些库工程,这样的话,开启并行构建才会发挥作用。并行构建开启方式是修改文件gradle.properties,加入如下行:
基础配置篇
全局基础配置管理
设置全局编码
如果导入一个windows下编写的项目,而代码中有中文注释,采用GBK, GB18030等编码方式时,编译会报错,可以采用如下方式统一项目的编码
设置全局编译器的版本
如果编程过程中采用了新版JDK(比如1.7)才支持的特性(比如new HashMap<>这样的写法),而编译的时候默认是旧版的JDK(比如1.6),这个时候编译会报错,采用如下方式可以指定用哪个版本的编译器编译,前提是JAVA_HOME指定的JDK是大于等于新版JDK的哦^o^,其他和java编译器相关的也可以在这里配置
如果不想全局生效,可以将tasks.withType(JavaCompile)放入某个子项目中。
配置签名信息
签名信息属于敏感信息,建议不要写死放到gradle脚本中,而是写到一个单独的配置文件里,而且这个配置文件不要同步到版本管理系统上,而是由本地维护,防止在版本管理平台上泄漏敏感信息。建议签名信息内容写到gradle.properties或者local.properties文件里,这样,gradle脚本可以直接引用,如果是放在一个自定义的文件中,gradle脚本需要提供相应的代码来读取文件的内容。
文件内容参考如下:
gradle脚本引用代码参考:
如果签名信息没有放到gradle.properties或者local.properties文件里,那就需要自己写代码读取咯,假设签名信息放在signing.properties文件中, 文件内容可以参考上面,读取文件的代码放入gradle脚本中就可以了,参考代码如下
设置第三方maven地址
其中name和credentials是可选项,视具体情况而定
GRADLE脚本拆分以及引用
如果一个gradle脚本太大,可以按照具体任务的类型拆分成几个子脚本,然后引入到主脚本中
全局变量定义及引用
可以在顶层build.gradle脚本中定义一些全局变量,提供给子脚本引用
子脚本引用
构建参数篇
构建参数设置
AndroidManifest占位符,BuildConfig以及资源配置
根据版本类型和构建变种定义不同的变量值供程序引用
buildConfigField支持Java中基本数据类型,如果是字符串,记得加转义后的双引号
resValue支持res/values下的资源定义,字符串无需叫转义后的双引号
设置支持的语言
利用这个配置可以去掉三方库中无用的语言
重命名产出的文件
需要将产出的aar/apk移到另外一个地方的时候
删除unaligned apk
删除无用的apk中间产物
将自定义的任务加入构建流程
有时候编写了一些自定义的任务,希望加入到构建流程中对输入做预处理或者对输出做后处理
比如这里app工程依赖library的构建,可以这样手工指定依赖关系
打包选项
有时候引用的三方库会带有一些配置文件xxxx.properties,或者license信息,打包的时候想去掉这些信息,就可以这样做
lint选项开关
lint会按默认选项会做严格检查,遇到包错误会终止构建过程,可以用如下开关关掉这个选项,不过最好是重视下lint的输出,有问题及时修复,避免潜在问题
依赖库篇
三方库(本地,maven)的依赖和工程库依赖关系
依赖库按构建目标定制
不同的依赖库可以按构建目标做定制,比如freemium的变种集成了广告,就可以这样写
aar本地库依赖
jar本地库的依赖很容易写,arr本地库的依赖稍微麻烦些
NDK篇
NDK配置
只保留某一个abi,比如arm-eabi
为了包大小的考虑,去掉多余的本地库
GRADLE 构建最佳实践的更多相关文章
- 转:GRADLE构建最佳实践
转自: http://www.figotan.org/2016/04/01/gradle-on-android-best-practise/#section-2 随着谷歌对Eclipse的无情抛弃和对 ...
- Gradle配置最佳实践
https://blog.csdn.net/devilnov/article/details/53321164 本文会不定期更新,推荐watch下项目.如果喜欢请star,如果觉得有纰漏请提交issu ...
- 8.云原生之Docker容器镜像构建最佳实践浅析
转载自:https://www.bilibili.com/read/cv15220861/?from=readlist 本章目录 0x02 Docker 镜像构建最佳实践浅析 1.Dockerfile ...
- Gradle最佳实践
一.Gradle相比Maven的优势 配置简洁 Maven是用pom.xml管理,引入一个jar包至少5行代码,Gradle只需要一行. 构建速度快 Gradle支持daemon方式运行,启动速度快, ...
- CI Weekly #18 | flow.ci iOS 最佳实践出炉,正式支持 Git@OSC 构建
如大家所期待,flow.ci 现已支持开源中国的代码仓库 - 码云,可以直接构建 Git@OSC 的项目了,点击创建项目-选择代码仓库-选择码云-绑定 OSChina 账户-选择要构建项目,教程看这里 ...
- Cocos Creator—最佳构建部署实践
这篇文章主要是我们团队在使用Cocos Creator过程中的一些关于部署方面的实践总结,标题党了一回,严格来说,应该是<快看漫画游戏研发团队使用Cocos Creator构建部署最佳实践> ...
- Web前端开发最佳实践(7):使用合理的技术方案来构建小图标
大家都对网站上使用的小图标肯定都不陌生,这些小图标作为网站内容的点缀,增加了网站的美观度,提高了用户体验,可是你有没有看过在这些网站中使用的图标都是用什么技术实现的?虽然大部分网站还是使用普通的图片实 ...
- MaxCompute 构建企业云数据仓库CDW的最佳实践建议
在本文中阿里云资深产品专家云郎分享了基于阿里云 MaxCompute 构建企业云数据仓库CDW的最佳实践建议. 本文内容根据演讲视频以及PPT整理而成. 大家下午好,我是云郎,之前在甲骨文做企业架构师 ...
- 使用nodejs构建Docker image最佳实践
目录 简介 准备nodejs应用程序 创建Dockerfile文件 创建.dockerignore文件 创建docker image 运行docker程序 node的docker image需要注意的 ...
随机推荐
- C语言学习总结(四) 剩余内容
第六章.剩余内容 (预处理指令,宏定义,条件编译,文件操作) 预处理指令 简单的来说就是在程序编译之前需要做的事情 1.宏定义 概念: 是一个替换代码的预处理指令,可以在编译之前进行代码替换(宏展开, ...
- jquery deferred
http://www.ruanyifeng.com/blog/2011/08/a_detailed_explanation_of_jquery_deferred_object.html http:// ...
- quartz定时任务时间配置
quartz定时任务时间设置描述(2011-03-03 16:23:50)转载▼标签: quartz时间it 分类: 凌乱小记 这些星号由左到右按顺序代表 : * * * ...
- 分析WordPress主题结构是如何架构的?
利用强大的技术,可以把基于WordPress的网站做成各种各样的形式,这除了要求WordPress主题开发人员精通HTML,PHP,JS,CSS等技术,还需要开发者掌握WordPress主题的框架.下 ...
- 最好的JAVA IDE IntelliJ IDEA使用简介(一)—之界面元素
打开IDEA,(当第一次打开的时候出现的是一个欢迎页面,随便创建一个project来进入到IDEA的主界面),主界面显示如下: 主界面由6个主要区域组成(图中红色数字标注的) 1.菜单和工具栏 2.导 ...
- .config-20150410
## Automatically generated file; DO NOT EDIT.# OpenWrt Configuration#CONFIG_MODULES=yCONFIG_HAVE_DOT ...
- [Exchange2013] 无法正常发送存入草稿箱 或者 只能发不能收
可能是由于你的域控的DNS设置导致: 1.那么首先我们添加一个EX的记录在域控的DNS里面 2.登录exchange的控制台,设置DNS Server
- [Citrix NetScaler] 简述
额 就这个题目 Citrix NetScaler 是一个VPN,一个代理,一个Gateway的存在,一个Citrix的产品 首先是我们利用Citrix NetScaler的测试环境: 架构上分2种: ...
- leetcode distinct-subsequences(DP)
参考https://oj.leetcode.com/problems/distinct-subsequences 动态规划方程 dp[i][j]=dp[i-1][j-1]+dp[i-1][j] (s( ...
- Axure初体验:简单交互、通过按钮切换图片
前言: 之前是一直用processon的UI原型设计,后来感觉只能完成静态页面的processon满足不了原型设计的需求,断网时候也不方便修改.展示.最终还是决定学习动态页面的制作,所选工具为原型设计 ...