为什么build.gradle看起来不像Groovy?

时间:2017-04-26 19:36:02

标签: android android-studio gradle groovy

我读到gradle是用groovy写的 但是我的build.gradle文件看起来并不像groovy 事实上,它根本不像一种语言。 这是我的build.gradle文件:

apply plugin: 'com.android.application'

android {
    compileSdkVersion 25
    buildToolsVersion "25.0.2"
    defaultConfig {
        applicationId "com.israelkariti.location2_1"
        minSdkVersion 14
        targetSdkVersion 25
        versionCode 1
        versionName "1.0"
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
}

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
        exclude group: 'com.android.support', module: 'support-annotations'
    })
    compile 'com.android.support:appcompat-v7:25.3.1'
    compile 'com.android.support.constraint:constraint-layout:1.0.0-beta4'
    compile 'com.google.android.gms:play-services-maps:10.2.1'
    testCompile 'junit:junit:4.12'
}

有人可以向我解释一下这种语法是什么 该语法如何是Groovy代码?
如果我遗漏了一些大事,请详细说明这件事是如何运作的 谢谢

1 个答案:

答案 0 :(得分:1)

好吧,Gradle为它的DSL添加了一些魔力,但从技术上讲,每个Gradle脚本都是完全有效的Groovy。

要了解dependenciesapply plugin:等所有内容,我们需要了解不同类型的Gradle脚本:

  • 构建脚本(build.gradle
  • 设置脚本(settings.gradle
  • 初始化脚本(例如init.gradle

所有这些脚本都在不同的范围内执行,因为它们被应用于"不同的对象。 Gradle调用此行为"附加委托对象"。

对于构建脚本(就像您提到的那样),此对象是Project。现在让我们分析您的Gradle脚本:

apply plugin: 'com.android.application'

Project接口扩展了PluginAware接口,该接口定义了apply方法Map<String,?>。在Groovy中,映射表示法为[key:value, ...],括号可以省略,类型String的映射键不用引号括起来。因此,plugin: 'com.android.application'只不过是一张Groovy地图,并将其移交给apply方法。

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    ...
}

我将继续使用此部分并完成android部分,因为它更容易理解:

dependencies不是Gradle关键字,它只是已经提到的Project接口的方法名称。此方法采用Closure,它包含在大括号内。再次省略普通方法调用括号。闭包在DependencyHandler对象上执行。现在我们只是为我们的配置添加依赖项。我们可以使用add方法并传递配置名称和依赖符号(以及可选的新闭包)。

这里开始Gradle魔法。对于项目ConfigurationContainer中的每个现有配置,将DependencyHandler添加一个具有相应配置名称的新方法,因此我们可以简单地使用此方法而不是{{1} }} 每时每刻。在为Java开发时,这些配置及其方法是addcompileruntime(以及其他)。 testCompile再一次只是Project界面的一种方法。

fileTree

Project接口定义的方法不是唯一可用的方法。 Gradle插件(如您正在使用的Android插件)可以添加扩展约定。这样,可以调用属性和方法,就像它们属于Project对象一样。这就是如何通过构建脚本中的闭包右侧配置android { compileSdkVersion 25 ... } 部分。

android关闭内部,会发生一些额外的Gradle魔法。您可能知道,在Groovy中,可以省略androidget部分并直接访问属性(尽管仍然可以调用getter或setter)。 Gradle还为每个属性添加了一个方法,该方法具有属性的名称,可以用作setter。这样,我们可以调用set方法来设置compileSdkVersion属性。再次,省略括号。这只是一些语法糖,它允许我们省略赋值运算符。

每当你开始一个新的大括号级别时,你基本上都使用一个闭包来配置一个对象。有时会创建一个新对象,有时会使用现有属性。有时,您需要阅读文档以了解究竟发生了什么。