一、前言

Gradle 是以 Groovy 语言为基础,面向Java应用为主。基于DSL(领域特定语言)语法的自动化构建工具。

上面这句话我觉得写得很官方,大家只需知道Gradle可以用来android开发中进行多个项目依赖的自动化编译脚本,知道这点也就知道我们使用它的目的;

为什么不使用Ant做自动化编译脚本,因为ant上手快,但是维护起来太不方便了,有了Gradle你可以跟项目组的同事说,用Ant的孩子们别苦逼的维护了,赶紧换成gradle吧。


本文面向gradle新手或者以前使用过gradle低版本的朋友,因为我感觉每次gradle升级那个脚本也有些坑爹,有些api就废弃掉了,不过总体感觉每次升级都让这个工具更加严谨话,易用话了。


二、Demo描述

下面我就简单写一个demo,通过这个demo程序让大家如何快速上手,比较实用的一个实例:

demo程序分为2个工程,你可以直接实用eclipse新建一个android工程,其实我也是这么干的,这样一来大家仔细看下图



这里顺便强调一下demo工程的环境配置:(很重要,否则下面被我坑了别怪我提起没跟你说)

jdk:C:\Program Files\Java\jdk1.8.0_20(注意:不要使用jre,gradle会提示你使用jdk的)

否则脚本会提示以下错误:

* What went wrong:Execution failed for task ':appcompat_v7:compileReleaseJava'.> Cannot find System Java Compiler. Ensure that you have installed a JDK (not just a JRE) and configured your JAVA_HOMEsystem variable to point to the according directory.
android-sdk:D:\dev\adt-bundle-windows-x86-20140702

android-api: 20, android4.4W(注意:做android开发你每次都是用最新的api编译是一个好习惯

gradle:2.1,(使用最新的版本2.2,no zuo no die,被坑不断,欢乐不断)

gradle的下载地址:http://www.gradle.org/documentation,大家可以看看文档,当然你的E文好的话,会容易上手,不过没关系,看了我写的文章你gradle的文档你可以不看了,因为很多东西你用不上,除非你项目中使用了特别复杂的功能

gradle2.1的api文档:http://www.gradle.org/docs/current/javadoc/org/gradle/api/Project.html,这个需要你偶尔翻翻,因为简单功能会用上的


环境变量配置

JAVA_HOME,GRADLE_HOME都要添加到环境变量里

当然了path变量里你也要加上 JAVA_HOME/bin,和GRADLE_HOME/bin,这样下面你开一个CMD命令行,才可以方面使用gradle build命令


好了准备工作完成后,我们就开始正式讲讲这个demo工程了


TestDemo工程就写了一个activity,显示hello world!

Appcompatv7工程大家懂得一个library,很有代表性,我们实际项目中会用到多个library,你可以举一反三了。


下面看看目录文件:


你想运行编译脚本,需要2个配置文件,local.properties和settings.gradle

settings.gradle里的代码内容:

include ':appcompat_v7', ':TestDemo'
这里面可以看到是project的描述,如果你有多个工程如论主工程还是引用的库工程,都需要在这里面声明,否则gradle找不到


local.properties里的代码内容:

sdk.dir=D:\\dev\\adt-bundle-windows-x86-20140702\\sdk
这里面可以看到是android sdk的目录,自己填好,否则也会报错。

好了下面讲讲每个工程里面都需要配置一个build.gradle 文件

appcompat_v7工程的build.gradle:

  

buildscript{repositories{mavenCentral();}dependencies{classpath 'com.android.tools.build:gradle:0.13.+' //如果使用gradle2.2版本,请改为gradle:0.14.+}tasks.withType(JavaCompile) { options.encoding = "UTF-8" }}apply plugin:'android-library'dependencies{compile fileTree(dir:'libs',include:"*.jar")}android{compileSdkVersion 20buildToolsVersion "20"enforceUniquePackageName=falselintOptions{abortOnError false}sourceSets{main{manifest.srcFile 'AndroidManifest.xml'java.srcDirs = ['src']resources.srcDirs  = ['src']aidl.srcDirs = ['src']renderscript.srcDirs = ['src']res.srcDirs = ['res']assets.srcDirs = ['assets']}}lintOptions{abortOnError false}}



对于这个文件我需要强调几点:

1、classpath 'com.android.tools.build:gradle:0.13.+' ,很多人用了低版本出了问题写什么0.11+,我不管,你要使用gradle2.1版本,这里就写成0.13.+包你没错。如果使用gradle2.2版本,这里就要写成0.14.+

2、apply plugin:'android-library',说明这个一个库工程,详细自己找资料脑补

3、tasks.withType(JavaCompile) { options.encoding = "UTF-8" } ,task是个啥自己查去,这里编译encoding配成UTF-8,还有一点在低版本脚本有的人写成tasks.withType(Compile) ,这样子报错了,改成JavaCompile吧,我是一点一点排错的

4、android{
compileSdkVersion 20
buildToolsVersion "20"

这里面version写20,为啥?上面你看看我的android-sdk api的版本就知道了,写成别的也可以,你要保证你本地androidsdk都有。





TestDemo工程里的几个文件:


build目录:是gradle执行编译时候生成的,里面好多内容,有兴趣自己翻翻看

output目录:我写得脚本,最后把build里的apk自动copy到这个目录,这个可以具体看脚本

blue_key:apk签名文件

build.gradle:你懂得

TestDemo工程里面的build.gradle



import java.util.regex.Pattern//import com.android.builder.DefaultManifestParserimport com.android.builder.core.DefaultManifestParserbuildscript{repositories{mavenCentral()}dependencies{classpath 'com.android.tools.build:gradle:0.13.+'}/***tasks.withType(Compile){options.encoding = "UTF-8"}**/tasks.withType(JavaCompile) { options.encoding = "UTF-8" }}apply plugin:'android'dependencies{compile fileTree(dir:"libs",include:'*.jar')compile project(':appcompat_v7')}android{compileSdkVersion 20buildToolsVersion "20"enforceUniquePackageName=falsedefaultConfig{targetSdkVersion 17;}lintOptions{abortOnError false}dexOptions {preDexLibraries = false}packagingOptions {exclude 'META-INF/DEPENDENCIES.txt'exclude 'META-INF/LICENSE.txt'exclude 'META-INF/NOTICE.txt'exclude 'META-INF/NOTICE'exclude 'META-INF/LICENSE'exclude 'META-INF/DEPENDENCIES'exclude 'META-INF/notice.txt'exclude 'META-INF/license.txt'exclude 'META-INF/dependencies.txt'exclude 'META-INF/LGPL2.1'exclude 'META-INF/ASL2.0'}signingConfigs{myConfig{storeFile file("bluekey")storePassword "blue"keyAlias "blue"keyPassword "blue"}}buildTypes{release{//runProguard true  //打开混淆开关 这种写法不可以了//proguardFile 'proguard.txt.txt'  //配置单个文件这样,这种写法不可以了
minifyEnabled true                  proguardFile getDefaultProguardFile('proguard-android.txt')//指定混淆文件signingConfigs.myConfig}}sourceSets{main{manifest.srcFile 'AndroidManifest.xml'java.srcDirs = ['src']resources.srcDirs = ['src']aidl.srcDirs = ['src']//rendersrcDirs = ['src']res.srcDirs = ['res']assets.srcDirs = ['assets']}}task copyNativeLibs(type: Copy) {        from(new File(project(':appcompat_v7').getProjectDir(), 'libs')) { include '**/*.so' }        into new File(buildDir, 'native-libs')    }tasks.withType(JavaCompile){compileTask -> compileTask.dependsOn copyNativeLibs}clean.dependsOn 'cleanCopyNativeLibs'tasks.withType( com.android.build.gradle.tasks.PackageApplication){pkgTask -> pkgTask.jniFolders = new HashSet<File>()pkgTask.jniFolders.add(new File(buildDir,'native-libs'))}}build.doLast {def today = new Date().format('yyMMdd');copy{//from('build/apk')from('build/outputs/apk')into('output')include('TestDemo-debug.apk')rename('TestDemo-debug.apk','blue-'+today+'-'+readVersion()+'-demo.apk')}}/***从Manifest.xml中读取版本号**/def readVersion(){def manifestParser = new DefaultManifestParser()return manifestParser.getVersionName(android.sourceSets.main.manifest.srcFile);}





对于这个文件我需要强调几点(很重要):

1、//import com.android.builder.DefaultManifestParser
import com.android.builder.core.DefaultManifestParser

//注释掉的代码是低版本的写法,目前使用最新api

2、 /***
tasks.withType(Compile){
options.encoding = "UTF-8"
}
**/

tasks.withType(JavaCompile) { options.encoding = "UTF-8" }

//注释掉的代码是低版本的写法,目前使用最新api

3、

dependencies{
compile fileTree(dir:"libs",include:'*.jar')
compile project(':appcompat_v7')
}

编译依赖,我们可以看到依赖的库 appcompat_v7要写在这里,注意":"(冒号一定要写)


4、

signingConfigs{
myConfig{
storeFile file("bluekey")
storePassword "blue"
keyAlias "blue"
keyPassword "blue"
}
}


buildTypes{
release{
signingConfigs.myConfig
}
}

编译时候签名文件配置,当然你也可以编译出debug和没有签名的apk,自行查资料去

5、

task copyNativeLibs(type: Copy) {
from(new File(project(':appcompat_v7').getProjectDir(), 'libs')) { include '**/*.so' }
into new File(buildDir, 'native-libs')
}



tasks.withType(JavaCompile){
compileTask -> compileTask.dependsOn copyNativeLibs
}

关于依赖的so文件和jar文件,在编译之前copy依赖到主工程的native-libs目录

6、build.doLast {
def today = new Date().format('yyMMdd');
copy{
//from('build/apk')
from('build/outputs/apk')
into('output')
include('TestDemo-debug.apk')
rename('TestDemo-debug.apk','blue-'+today+'-'+readVersion()+'-demo.apk')
}
}

/**
*从Manifest.xml中读取版本号
**/
def readVersion(){
def manifestParser = new DefaultManifestParser()
return manifestParser.getVersionName(android.sourceSets.main.manifest.srcFile);
}

build.doLast,就是最后执行的意思,关于gradle task大家需要简单查资料掌握即可。


这里面需要注意的:

def today = new Date().format('yyMMdd');

def manifestParser = new DefaultManifestParser()

都需要def声明变量,低版本不用写的,但是目前不写就要报错了。

这个代码的功能:就是从Manifest文件里读出versioncode然后结合当前日期重新命名output里的apk文件。



方便吧,很实用的一点。

7、apply plugin:'android'

这说明这个脚本需要编译的是一个 android工程,跟上面的library是不是有所不同呢? gradle还支持java project的编译,大家自行查资料。


三、编译执行:

下面我们打开cmd命令窗口进行编译操作



在TestDemo目录执行gradle build,因为这里是local.properties和settings.gradle 所在的根目录。

第一次执行时候,gradle根据依赖去下载所需要的jar包,会在你每个工程里创建一个.gradle目录

dependencies{
classpath 'com.android.tools.build:gradle:0.13.+'
}

下载成功后



ok,那我们开始执行编译操作了,gradle build



编译正常的话会提示 BUILD SUCCESSFUL,然后自己去output目录找apk去。


这里提醒大家一个jar冲突会引起编译中断的问题:


因为很多朋友的project的libs目录有多个android-support-v4.jar导致的。


最后啰嗦

今天先写到这,我们实际运用中有很多需求,例如:自动根据多渠道打包,根据不同的资源和不同的pkg进行apk打包,gradle都能帮你搞定,这块demo后续有时间我贴上来。 有什么问题,大家可以跟我交流(QQ群: 221057495)。


四、参考资料:

After upgrading to Gradle 2.0: Could not find property 'Compile' on root project
Unable to resolve class in build.gradle using Android Studio 0.60/Gradle 0.11

How to configure build.gradle files of an existing project with actionbarsherlock lib?
Multiple settings gradle files for multiple projects building

Android Tools Project Site


五、扩展阅读:

引用配置文件里的变量,例如:我们可以引用gradle.properties

sdk.dir=C:\\haha\\dev\\adt-bundle-windows-x86_64-20140702\\sdk

在我们的build.gradle文件中如果要想引用sdk.dir

可以如下操作:

使用 project.hasProperty('sdk.dir') 判断key值是否存在
使用project.properties['sdk.dir']进行key值的value引用


demo下载地址:

gradle2.1demo教程(多评论哈)

更多相关文章

  1. [置顶] 解决android某些应用开发某些类无法解析/找到的问题--使
  2. Android(安卓)源码编译加速 使用ccache
  3. 在 Ubuntu 下使用 Android(安卓)NDK r4b 编译 FFmpeg 0.6.3
  4. android 加载外部 dex文件中的类 的源码实例
  5. android解析xml文件的方式之DOM解析
  6. android app卸载以后弹出用户反馈界面
  7. Android实现自定义铃音
  8. Windows环境下Android(安卓)NDK的开发
  9. Android导出与使用带资源的lib包

随机推荐

  1. Android中文API(119)——TableRow
  2. 安卓巴士Android开发神贴整理
  3. android控件属性
  4. RatingBar 修改 颜色 大小 图片
  5. Android:带你玩转Servie,子线程,与UI线程通
  6. 在Android(安卓)app中切换自定义的输入法
  7. 在android中使用jsoup解析页面链接
  8. 浅谈Android手机终端客户端的适配测试
  9. Android(安卓)开发者从0到1发布一个微信
  10. Android(安卓)蓝牙开发基本流程