2015-04-06 4 views
5

Что делает следующий синтаксис заводной действительно означает?Пожалуйста, объясните Android build.gradle заводной синтаксис

The Gradle docs tout, как build.gradle является только groovy. Команда Android упростила сборку по умолчанию build.gradle до такой степени, что она не выглядит как код (по крайней мере, для меня). Пожалуйста, объясните, что это делает с точки зрения сильного синтаксиса. Например, являются ли эти объявления глобальных переменных, которые использует плагин Android?

Бонусные баллы, если вы включили ссылки на http://groovy-lang.org/syntax.html как часть вашего объяснения.

apply plugin: 'com.android.application' 

android { 
    compileSdkVersion 21 
    buildToolsVersion "21.1.2" 

    defaultConfig { 
     applicationId "com.crittercism" 
     minSdkVersion 15 
     targetSdkVersion 21 
     versionCode 5 
     versionName "5.0" 
    } 

} 

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

ответ

3

Благодаря AndroidGuy для предоставления отличного видео, которое сообщило мне информацию ниже. Видео длится 35 минут, так что вот TL, DR.

Большая часть этого синтаксиса представляет собой смесь method звонков и closures. Затворы представлены фигурными скобками. Также обратите внимание, что вызовы методов не требуют скобок.

apply plugin: 'com.android.application' 

Это вызов apply метод на project объекта с одним именем параметра «плагин». Объектом проекта является объект верхнего уровня, предоставленный Gradle.

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

Это установка dependencies свойство объекта проекта. Groovy properties в основном сокращены для геттеров и сеттеров. Свойство зависимостей является объектом Closure, который делегирует DependencyHandler. Groovy delegation - это, по сути, способ увеличить разрешение области закрытия. Закрытие зависимостей содержит единственный метод для компиляции, который принимает позиционный параметр FileTree. FileTree генерируется методом fileTree, который определен в объекте проекта. Метод компиляции все еще немного туман. Похоже, что оно исходит от Java plugin, но там явно не указано. Часть «компиляции» все еще немного волшебна для меня.

android { 
    ... 
} 

Я оставлю раздел «андроид» в качестве упражнения для читателя. Специфический язык домена Gradle Android (DSL) недоступен в Интернете. Вы должны download it.

2

Я знаю, что я должен не просто разместить ссылку в качестве ответа, но на самом деле нет лучшего объяснения, чем это:

"An introduction to Groovy, Gradle and the Android plugin" by Daniel Lew

+1

Хотя эта ссылка может ответить на вопрос, лучше включить основные части ответа здесь и предоставить ссылку для справки. Ответные ссылки могут стать недействительными, если связанная страница изменяется –

5

Вы можете думать о Gradle сценария сборки, как некоторый код который делегирован объекту, который может отвечать на вызовы метода, написанные на нем.

Скрипт использует много Groovy синтаксического сахара, поэтому удаление их, он должен выглядеть следующим образом:

Так что сценарий действительно куча вызовов метода:

  • def apply(Map)
  • def android(Closure)
  • def dependencies(Closure)

Это android(Closure) получит замыкание и делегирует методы, называемые в нем объект, который может ответить на эти методы:

  • def compileSdkVersion(Integer)
  • def buildToolsVersion(String)
  • ...

Учитывая что, мы можем разобрать скрипт, передать его некоторому объекту и t купите его.

Делегирование с использованием DelegatingBaseScript это один из способов сделать это (не уверен, что если Gradle делает это таким образом). Вот упрощенных вниз рабочая версия:

import org.codehaus.groovy.control.CompilerConfiguration 

gradleScript = ''' 
apply plugin: 'com.android.application' 

android({ 
    compileSdkVersion(21) 
    buildToolsVersion("21.1.2") 
})''' 


class PocketGradle { 
    def config = [apply:[]].withDefault { [:] } 

    def apply(map) { 
    config.apply << map.plugin 
    } 

    def android(Closure closure) { 
    closure.delegate = new Expando(
     compileSdkVersion: { Integer version -> 
      config.android.compileSdkVersion = version 
     }, 
     buildToolsVersion : { String version -> 
      config.android.buildToolsVersion = version 
     }, 
    ) 
    closure() 
    } 
} 

def compiler = new CompilerConfiguration(scriptBaseClass: DelegatingScript.class.name) 

shell = new GroovyShell(this.class.classLoader, new Binding(), compiler) 

script = shell.parse gradleScript 
script.setDelegate(gradle = new PocketGradle()) 
script.run() 

assert gradle.config == [ 
    apply: ['com.android.application'], 
    android: [ 
    compileSdkVersion: 21, 
    buildToolsVersion: '21.1.2' 
    ] 
] 

Вы можете выполнить скрипт в Groovy Web Console (нажмите на кнопку «Редактировать в консоли», а затем «Выполнить скрипт»).

Большая часть синтаксиса объяснения находятся в DSL section:

  1. командной цепи

Groovy позволяет опустить скобки вокруг аргументов в вызове метода для отчетности верхнего уровня. Функция «цепочка команд» расширяет это, позволяя нам связывать вызовы методов без круглых скобок, не требуя ни круглых скобок вокруг аргументов, ни точек между цепочечными вызовами.

Существует также Groovy ConfigSlurper, но я не уверен, что он может зайти так далеко, как хочет Gradle.

Смежные вопросы