困惑的build.gradle
在由Eclipse转到Android Studio之后,第一个让我感到困惑的是build.gradle这个文件了,实在话,当时我并不知道这么写是几个意思。
apply plugin: 'com.android.application'
android {
compileSdkVersion 21
buildToolsVersion "21.1.2"
defaultConfig {
applicationId "com.example.test"
minSdkVersion 17
targetSdkVersion 21
versionCode 1
versionName "1.0"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
compile 'com.android.support:appcompat-v7:21.0.3'
}
如上就是建立一个as工程生成的基本构建文件了,暂且不需要知道他底层怎么实现,至少要知道这么写是几个意思,为何要这么写,我们需要一步一步来揭穿它。
一:Gradle 是基于Groovy语言来构建的,第一点就得了解什么是Groovy语言,以及它的语法。
Groovy是一种动态语言,是从Java语言进化而来,可以说是Java的加强,它能运行于JVM上,具体的一些介绍可以自行谷歌了解,这里只是为了简单的看懂Groovy和基本使用。
开发环境:
Eclipse Groovy开发插件 http://dist.springsource.org/release/GRECLIPSE/e4.4 后边的e4.x要自己对照自己的eclipse版本,否则可能出现无法安装的问题,我的是4.4。
第一个Groovy程序:
右键,新建一个Groovy工程,添加一个groovy资源包(只是为了区分),然后在src下先新建一个JavaTest.java类,勾选main方法,关在方法里写下一行代码打印一个字符串 Hello groovy!
public class JavaTest {
public static void main(String[] args) {
System.out.println("Hello groovy!");
}
}
上面是一个很简单的Java类,运行之后将会在控制台输出Hello groovy!
然后同理,我们在groovy资源包下新建一个GroovyTest.groovy 选择新建-other-Grooovy Class
class GroovyTest {
static main(args) {
println "Hello groovy!"
}
}
右键使用Groovy运行后,也会在控制台上打印出 Hello groovy!
相比于JavaTest.java我们发现,GroovyTest.groovy。似乎和JavaTest.java长得很像,只不过是将JavaTest.java去掉了一些内容,如class的修饰符public ,打印的System.out ,参数args的类型String[]。下面我们对GroovyTest.groovy做一些改动:
class GroovyTest {
static main(args) {
System.out.println "Hello groovy!"
}
}
运行之后发现一样能输入Hello groovy!, 有意思,有意思,那我们再给args加上String[]的类型能,
class GroovyTest {
static main(String[] args) {
System.out.println.println "Hello groovy!"
}
}
发现一样能运行,并且同样输入Hello groovy! ,有趣了,是不是说我把java里面的代码都拷过来也能运行呢,这时变成这样:
public class GroovyTest {
public static void main(String[] args) {
System.out.println("Hello groovy!");
}
}
和你想的结果一样,他也准确无语的输出了Hello groovy!,哦,原来和我们看到的一些说明是正确的,groovy和java代码是一样的,它只不过是对java代码进行简化了。
不是说简化吗,假如我把GroovyTest类的代码简化成这样:
println "Hello groovy!"
运行后,发现居然可以输出来Hello groovy!
下面是一些说明:
因为groovy是动态语言,就跟js一样,Groovy对于类型的定义都用def这个关键字来声明,它在底层会自动判断当前的变量是一个什么类型:
我们在上面也看到GroovyTest.groovy文件中,只写了一个println "Hello groovy!" 也是可以正常运行的,所以以下我们都用最简化直接在文件中输入这些代码。
定义一个字符串
def aa="Hello"
println aa
假如把打印跟定义换个位置,将会报错
println aa
def aa="Hello"
由此看来,groovy也是由上到下来运行的,看起来像是把这些都放到main之中去运行。
//先定义再赋值
def str
str="r"
println str
定义一个整形
def num=10
println num
定义一个整形数组集合
def colum=[2,3,4,5]
println colum[0]
因为groovy已经重载了<<所以我们可以用<<来向集合加入一个值
def strArry=["jin","mu","shui"]
strArry.add("huo")
strArry << "tu"
println strArry
//输出:[jin, mu, shui, huo, tu]
定义一个Map类型
def map=[key:"name",value:"mjk"]
println map["key"]
println map["value"]
输出:
name
mjk
只要看到是 key:value都是map类型,因为key会自动转换成string,所以你可以写成def map=["key":"name","value":"mjk"]也可以写成def map=[key:"name",value:"mjk"]
如果想知道当前这个变量是一个什么类型可以用 .class来打印
def str="I am string"
println str.class
输出:class java.lang.String
循环的使用:
def arry=["a","b","c","d"]
for(a in arry){
println a
}
定义一个方法,接收两个参数,输出它们的和
def num=10
def method(a,b){
println a+b
}
method num,9
当然使用method(num,9)是一样的,只是去掉了括号,参数之间用逗号隔开
在定义一个map类型的时候,一定要加[],如果不加会报错,而在方法调用时,可以不加[],如果方法调用的map参数要加[],则必须在外部加()
如:
//打印 map值
def printMap(map){
println map["key"]
}
printMap key:"name"
输出:name
//定义一个方法,打印接收到的值
def printStr(str){
println str
}
printStr "Hello groovy!"
定义闭包:
闭包是Groovy里面一个很重要的特性,这里要着重讲,
先看一个groovy对集合本身的实现了的一个包含闭包的方法each
def acoll = ["妈妈", "爸爸", "我"]
acoll.each{
println it
}
输出:
妈妈
爸爸
我
acoll是一个字符串的集合,这个集合里面有一个方法叫each,接收一个参数,这个参数是一个闭包,因为闭包也是一种类型,所以它也能像变量一样当参数传递给方法使用。我们这里简单的理解,闭包是一个用花括号{}括起来的代码块,这个代码块在被触发的时候调用。
上面each中的it是一个关键字,它保存了返回到这个闭包中的一个值。下面我们来用自己的方法实现这个each
//定义一个方法,这个方法接收一个集合参数跟一个闭包,当方法被调用时,遍历集合里面的值,并把值传回给闭包
def myEach(arry,block){
for(i in arry){
block(i)
}
}
def arr=["爸爸","妈妈","我"]//字符串集合
//调用myEach方法
myEach(arr,{
println it
});
输出:
爸爸
妈妈
我
原来流程是这样,当我们调用myEach方法时,要传入一个集合arr,和闭包。当方法,myEach在遍历集合的时候,每得到一个值 就会回调一下这个闭包并把值传给它,从这里看是不是觉得,这个闭包既像一个变量参数,又像一个方法呢。
定义一个闭包并调用它:
//因为闭包是一种类型,所以在定义的时候要用=来给它赋值,这是跟方法有本质的区别
def block={
println "调用block"
}
block()
输出:调用block
定义一个闭包并传入一个参数
def block={
println "调用block"+it
}
block("--并传入参数")
输出:调用block--并传入参数
要是我们不想用it这个关键字,也是可以定义自己的关键字的,只是我们要使用->来告诉它,是用我们自己定义的变量来接收值,而不用it
def block={param ->
println "调用block"+param
}
block("--并传入参数")
//两个参数
def block={param1,param2->
println "调用block"+param1+param2
}
block("--参数1","参数2")
下面我们定义一个block,这个block是用来打印接收到的值,目的是去遍历给定的集合
def block={data->
println "value="+data
}
//定义一个方法,这个方法接收一个集合参数跟一个闭包,当方法被调用时,遍历集合里面的值,并把值传回给闭包
def myEach(arry,block){
for(i in arry){
block(i)
}
}
def arr=["爸爸","妈妈","我"]//字符串集合
//调用myEach方法
myEach(arr,block)
输出:
value=爸爸
value=妈妈
value=我
我们知道方法的括号是可以去掉的,如果上面调用方法时我们去掉括号就变成了:
//原来的是:myEach(arr,block)
myEach arr,block
而如果只是接收一个闭包的方法就可以写成:
myEach block
如果block是匿名的,那就成为:
myEach {
}
所以我们可以知道,集合的each方法是怎么实现遍历的,当我们的这个集合已经知道了里面的值,调用each时,只需要传入一个闭包参数,就可以得到每一个值。
一般来说,如果有多个参数,而最后一个为闭包的时候,调用方法的时候习惯写成:
myEach(param1,param2,param3){
}
实例:
//定义一个方法,这个方法接收一个集合参数跟一个闭包,当方法被调用时,遍历集合里面的值,并把值传回给闭包
def myEach(arry,block){
for(i in arry){
block(i)
}
}
def arr=["爸爸","妈妈","我"]//字符串集合
//调用myEach方法,并传入一个集合跟一个匿名的闭包
myEach (arr){data->
println "value="+data
}
到此差不多把groovy里面的一些基本的语法说完了。下面讲一下gradle
二:gradle
Gradle是一个构建工具,感兴趣的可以去官网上了解,它的构建是基于一个一个的任务,task。我觉得把groovy弄懂了,对于gradle只是多去看一下开发指南就行,这里不再说明。
三:回到build.gradle
讲完了上面,这个时候可以把开篇的build.gradle贴到这里说了,直接在代码里面加解释:
//这一行,一看就知道调用了一个方法叫apply 传入一个map类型的参数,key是plugin ,plugin的值是"com.android.application"说明是一个android应用工程
//在gradle中有介绍把你自己的一组代码,构建做成一个plugin,如果把plugin的值改成"com.android.library"就说明这是一个库工程
apply plugin: 'com.android.application'
//android这个方法接收一个闭包,在闭包里,调用的compileSdkVersion, buildToolsVersion等方法并给他们传值,并且还调用了defaultConfig这个方法来做一些配置,这个方法也是接收一个闭包,可以想象,通过闭包回调可以对值进行设置,当调用defaultConfig方法的时候,方法里面会先调用传入的这个闭包来初始化一些值,然后再进行别的其他操作。这也就是闭包的魅力所在。
android {
compileSdkVersion 21
buildToolsVersion "21.1.2"
defaultConfig {
applicationId "com.example.test"
minSdkVersion 17
targetSdkVersion 21
versionCode 1
versionName "1.0"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
compile 'com.android.support:appcompat-v7:21.0.3'
}
通过以上这些讲解,希望读者们能对build.gadle文件有一些认识,这样你也可以自己修改build.gadle文件来完成你自己想要的构建流程。
另外大家可以在这里找到关于Gradle一些内置的方法还有他们的功能,以及AS为android工程提供的一些方法:
http://google.github.io/android-gradle-dsl/current/