GVKun编程网logo

Android Gradle Plugin指南(一)——简介(android gradle plugin version)

2

如果您对AndroidGradlePlugin指南感兴趣,那么本文将是一篇不错的选择,我们将为您详在本文中,您将会了解到关于AndroidGradlePlugin指南的详细内容,我们还将为您解答一——

如果您对Android Gradle Plugin指南感兴趣,那么本文将是一篇不错的选择,我们将为您详在本文中,您将会了解到关于Android Gradle Plugin指南的详细内容,我们还将为您解答一——简介的相关问题,并且为您提供关于Android Gradle Plugin指南(三)——依赖关系、android库和多项目配置、Android Gradle Plugin指南(二)——基本项目、Android Gradle Plugin指南(六)——高级构建定制、android gradle 和 gradle plugin的有价值信息。

本文目录一览:

Android Gradle Plugin指南(一)——简介(android gradle plugin version)

Android Gradle Plugin指南(一)——简介(android gradle plugin version)

原文地址:http://tools.android.com/tech-docs/new-build-system/user-guide#TOC-Introduction


译者:google推出了全新的Android Studio集成开发环境,其中Android项目的结构与Eclipse的Android项目结构有很大的区别,原因就在于两开发环境使用的构建工具不同。Android Studio使用Gradle构建工具,Eclipse的ADT插件使用的是Ant构建工具。因为两个构建工具的区别,导致习惯了Eclipse开发环境的开发者刚开始比较难适应Android Studio。如果要迁移到Android Studio,建议最好了解下Gradle构建工具。Gradle构建工具是任务驱动型的构建工具,并且可以通过各种Plugin插件扩展功能以适应各种构建任务。对应Android项目的Gradle插件就是Android Gradle Plugin。本文是Google官方的Android Gradle Plugin使用指南翻译,以方便我大天朝开发者学习。如英语水平还不错的同学,建议直接查看官方原文,本人的理解和翻译难免有所疏漏。


1、Introduction(简介)


本文档适用于0.9版本的Gradle plugin。由于我们在1.0版本之前介绍的不兼容,所以早期版本可能与本文档有所不同。

1.1 Goals of the new Build System(gradle构建系统的目标)


采用Gradle作为新构建系统的目标:
    * 让重用代码和资源变得更加容易。
    * 让创建同一应用程序的不同版本变得更加容易,无论是多个apk发布版本还是同一个应用的不同定制版本。
    * 让构建过程变得更加容易配置,扩展和定制。
    * 整合优秀的IDE

1.2 Why Gradle?(为什么使用gradle)


Gradle是一个优秀的构建系统和构建工具,它允许通过插件创建自定义的构建逻辑。
我们基于Gradle以下的一些特点而选择了它:
    * 采用了Domain Specific Language(DSL语言)来描述和控制构建逻辑。
    * 构建文件基于Groovy,并且允许通过混合声明DSL元素和使用代码来控制DSL元素以控制自定义的构建逻辑。
    * 支持Maven或者Ivy的依赖管理。
    * 非常灵活。允许使用最好的实现,但是不会强制实现的方式。
    * 插件可以提供自己的DSL和API以供构建文件使用。
    * 良好的API工具供IDE集成。

2、Requirements(要求)


    * Gradle 1.10 或者 Gradle 1.11 或者 Gradle 1.12,并使用0.11.1插件版本。
    * SDK build tools 要求版本19.0.0。一些新的特征可能需要更高版本。


Android Gradle Plugin指南(三)——依赖关系、android库和多项目配置

Android Gradle Plugin指南(三)——依赖关系、android库和多项目配置

原文地址:http://tools.android.com/tech-docs/new-build-system/user-guide#TOC-Dependencies-Android-Libraries-and-Multi-project-setup


4、Dependencies,Android Libraries and Multi-project setup(依赖关系,Android库和多项目设置)


Gradle项目可以依赖于其它组件。这些组件可以是外部二进制包,或者是其它的Gradle项目。


4.1 Dependencies on binary packages(依赖二进制包)


4.1.1 Local packages(本地包)


配置一个外部库的jar包依赖,你需要在compile配置中添加一个依赖。

dependencies {
        compile files(''libs/foo.jar'')
    }

    android {
        ...
    }


注意:这个dependencies DSL标签是标准Gradle API中的一部分,所以它不属于android标签。


这个compile配置将被用于编译main application。它里面的所有东西都被会被添加到编译的classpath中,同时也会被打包进最终的APK。

以下是添加依赖时可能用到的其它一些配置选项:

    * compile:main application(主module)。

    * androidTestCompile:test application(测试module)。

    * debugCompile:debug Build Type(debug类型的编译)。

    * releaseCompile:release Build Type(发布类型的编译)。

因为没有可能去构建一个没有关联任何Build Type(构建类型)的APK,APK默认配置了两个或两个以上的编译配置:compile和<buildtype>Compile.

创建一个新的Build Type将会自动创建一个基于它名字的新配置。


这对于debug版本需要使用一个自定义库(为了反馈实例化的崩溃信息等)但发布版本不需要,或者它们依赖于同一个库的不同版本时会非常有用。


4.2.2 Remote artifacts(远程文件)


Gradle支持从Maven或者Ivy仓库中拉取文件。


首先必须将仓库添加到列表中,然后必须在依赖中声明Maven或者Ivy声明的文件。

repositories {
        mavenCentral()
    }


    dependencies {
        compile ''com.google.guava:guava:11.0.2''
    }

    android {
        ...
    }

注意:mavenCentral()是指定仓库URL的简单方法。Gradle支持远程和本地仓库。

注意:Gradle会遵循依赖关系的传递性。这意味着如果一个依赖本身依赖于其它东西,这些东西也会一并被拉取回来。


更多关于设置依赖关系的信息,请参考Gradle用户指南和DSL文档。


4.2 Multi project setup(多项目设置)


Gradle项目也可以通过使用多项目配置依赖于其它Gradle项目。


多项目配置的实现通常是在一个根项目路径下将所有项目作为子文件夹包含进去。



例如,给定以下项目结构:

MyProject/
     + app/
     + libraries/
        + lib1/
        + lib2/


我们可以定义3个项目。Grand将会按照以下名字映射它们:

    :app

    :libraries:lib1

    :libraries:lib2


每一个项目都拥有自己的build.gradle文件来声明自己如何构建。

另外,在根目录下还有一个setting.gradle文件用于声明所有项目。

这些文件的结构如下:

MyProject/
     | settings.gradle
     + app/
        | build.gradle
     + libraries/
        + lib1/
           | build.gradle
        + lib2/
           | build.gradle

其中setting.gradle的内容非常简单:

include '':app'', '':libraries:lib1'', '':libraries:lib2''

这里定义了哪一个文件夹才是真正的Gradle项目。


其中:app项目可能依赖于这些库,这是通过以下依赖配置声明的:

dependencies {
        compile project('':libraries:lib1'')
    }


更多关于多项目配置的信息请参考这里。


4.3 Library projects(库项目)


在上面的多项目配置中,:libraries:lib1和:libraries:lib2可能是一个Java项目,并且:app这个Android项目将会使用它们的jar包输出。


但是,如果你想要共享代码来访问Android API或者使用Android样式的资源,那么这些库就不能是通常的Java项目,而应该是Android库项目。


4.3.1 Creating a Library Project(创建一个库项目)


一个库项目与通常的Android项目非常类似,只是有一点小区别。


尽管构建库项目不同于构建应用程序,它们使用了不同的plugin。但是在内部这些plugin共享了大部分相同的代码,并且它们都由相同的com.android.tools.build.gradle.jar提供。

buildscript {

        repositories {

            mavenCentral()

        }


        dependencies {

            classpath ''com.android.tools.build:gradle:0.5.6''

        }

    }


    apply plugin: ''android-library''


    android {

        compileSdkVersion 15

    }

这里创建了一个使用API 15编译SourceSet的库项目,并且依赖关系的配置方法与应用程序项目的配置方法一样,同样也支持自定义配置。


4.3.2 Differences between a Project and a Library Project(普通项目和库项目之间的区别)


一个库项目的main输出是一个.aar包(它代表Android的归档文件)。它组合了编译代码(例如jar包或者是本地的.so文件)和资源(manifest,res,assets)。

一个库项目同样也可以独立于应用程序生成一个测试用的apk来测试。


标识Task同样适用于库项目(assembleDebug,assembleRelease),因此在命令行上与构建一个项目没有什么不同。


其余的部分,库项目与应用程序项目一样。它们都拥有build type和product flavor,也可以生成多个aar版本。

记住大部分Build Type的配置不适用于库项目。但是你可以根据库项目是否被其它项目使用或者是否用来测试来使用自定义的sourceSet改变库项目的内容。


4.3.3 Referencing a Library(引用一个库项目)


引用一个库项目的方法与引用其它项目的方法一样:

dependencies {

        compile project('':libraries:lib1'')

        compile project('':libraries:lib2'')

    }


注意:如果你要引用多个库,那么排序将非常重要。这类似于旧构建系统里面的project.properties文件中的依赖排序。


4.3.4 Library Publication(库项目发布)


一般情况下一个库只会发布它的release Variant(变种)版本。这个版本将会被所有引用它的项目使用,而不管它们本身自己构建了什么版本。这是由于Gradle的限制,我们正在努力消除这个问题,所以这只是临时的限制。


你可以控制哪一个Variant版本作为发行版:

android {

        defaultPublishConfig "debug"

    }

注意这里的发布配置名称引用的是完整的Variant版本名称.Relesae,debug只适用于项目中没有其它特性版本的时候使用。如果你想要使用其它Variant版本取代默认的发布版本,你可以:

android {

        defaultPublishConfig "flavor1Debug"

    }


将库项目的所有Variant版本都发布也是可能的。我们计划在一般的项目依赖项目(类似于上述所说的)情况下允许这种做法,但是由于Gradle的限制(我们也在努力修复这个问题)现在还不太可能。

默认情况下没有启用发布所有Variant版本。可以通过以下启用:

android {

        publishNonDefault true

    }


理解发布多个Variant版本意味着发布多个arr文件而不是一个arr文件包含所有Variant版本是非常重要的。每一个arr包都包含一个单一的Variant版本。

发布一个变种版本意味着构建一个可用的arr文件作为Gradle项目的输出文件。无论是发布到一个maven仓库,还是其它项目需要创建一个这个库项目的依赖都可以使用到这个文件。


Gradle有一个默认文件的概念。当添加以下配置后就会被使用到:

compile project('':libraries:lib2'')


创建一个其它发布文件的依赖,你需要指定具体使用哪一个:

dependencies {

        flavor1Compile project(path: '':lib1'', configuration: ''flavor1Release'')

        flavor2Compile project(path: '':lib1'', configuration: ''flavor2Release'')

    }


重要:注意已发布的配置是一个完整的Variant版本,其中包括了build type,并且需要像以上一样被引用。

重要:当启用非默认发布,maven发布插件将会发布其它Variant版本作为扩展包(按分类器分类)。这意味着不能真正的兼容发布到maven仓库。你应该另外发布一个单一的Variant版本到仓库中,或者允许发布所有配置以支持跨项目依赖。

Android Gradle Plugin指南(二)——基本项目

Android Gradle Plugin指南(二)——基本项目

原文地址:http://tools.android.com/tech-docs/new-build-system/user-guide#TOC-Basic-Project


3、Basic Project(基本项目)


一个Gradle项目的构建过程定义在build.gradle文件中,位于项目的根目录下。

3.1 Simple build files(简单的构建文件)


一个最简单的Gradle纯Java项目的build.gradle文件包含以下内容:

apply plugin: ''java''
这里引入了Gradle的Java插件。这个插件提供了所有构建和测试Java应用程序所需要的东西。

最简单的Android项目的build.gradle文件包含以下内容:
buildscript {
        repositories {
            mavenCentral()
        }

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

    apply plugin: ''android''

    android {
        compileSdkVersion 19

        buildToolsVersion "19.0.0"

    }
这里包括了Android build file的3个主要部分:

buildscrip{...}这里配置了驱动构建过程的代码。
在这个部分,它声明了使用Maven仓库,并且声明了一个maven文件的依赖路径。这个文件就是包含了0.11.1版本android gradle插件的库。
注意:这里的配置只影响控制构建过程的代码,不影响项目源代码。项目本身需要声明自己的仓库和依赖关系,稍后将会提到这部分。

接下来,跟前面提到的Java Plugin一样添加了android plugin。

最后,andorid{...}配置了所有android构建过程需要的参数。这里也是Android DSL的入口点。
默认情况下,只需要配置目标编译SDK版本和编译工具版本,即compileSdkVersion和buildToolsVersion属性。
这个complieSdkVersion属性相当于旧构建系统中project.properites文件中的target属性。这个新的属性可以跟旧的target属性一样指定一个int或者String类型的值。

重要:你只能添加android plugin。同时添加java plugin会导致构建错误。

注意:你同样需要在相同路径下添加一个local.properties文件,并使用sdk.dir属性来设置SDK路径。
另外,你也可以通过设置ANDROID_HOME环境变量,这两种方式没有什么不同,根据你自己的喜好选择其中一种设置。
                

3.2 Project Structure(项目结构)


上面提到的基本的构建文件需要一个默认的文件夹结构。Gradle遵循约定优先于配置的概念,在可能的情况尽可能提供合理的默认配置参数。

基本的项目开始于两个名为“source sets”的组件,即main source code和test code。它们分别位于:
    * src/main/
    * src/androidTest/

里面每一个存在的文件夹对应相应的源组件。
对于Java plugin和Android plugin来说,它们的Java源代码和资源文件路径如下:
    * java/
    * resources/

但对于Android plugin来说,它还拥有以下特有的文件和文件夹结构:
    * AndroidManifest.xml
    * res/
    * assets/
    * aidl/
    * rs/
    * jni/

注意:src/androidTest/AndroidManifest.xml是不需要的,它会自动被创建。

3.2.1 Configuring the Structure(配置项目结构)

当默认的项目结构不适用的时候,你可能需要去配置它。根据Gradle文档,重新为Java项目配置sourceSets可以使用以下方法:

sourceSets {
        main {
            java {
                srcDir ''src/java''

            }

            resources {

                srcDir ''src/resources''

            }

        }
    }
注意:srcDir将会被添加到指定的已存在的源文件夹中(这在Gradle文档中没有提到,但是实际上确实会这样执行)。
    
替换默认的源代码文件夹,你可能想要使用能够传入一个路径数组的srcDirs来替换单一的srcDir。以下是使用调用对象的另一种不同方法:
sourceSets {
        main.java.srcDirs = [''src/java'']
        main.resources.srcDirs = [''src/resources'']
    }

想要获取更多信息,可以参考Gradle文档中关于 Java Pluign的部分。

Android Plugin使用的是类似的语法。但是由于它使用的是自己的sourceSets,这些配置将会被添加在android对象中。
以下是一个示例,它使用了旧项目结构中的main源码,并且将androidTest sourceSet组件重新映射到tests文件夹。
android {
        sourceSets {
            main {
                manifest.srcFile ''AndroidManifest.xml''
                java.srcDirs = [''src'']

                resources.srcDirs = [''src'']
                aidl.srcDirs = [''src'']

                renderscript.srcDirs = [''src'']

                res.srcDirs = [''res'']
                assets.srcDirs = [''assets'']

            }


            androidTest.setRoot(''tests'')
        }
    }

注意:由于旧的项目结构将所有的源文件(java,aidl,renderscripthe和java资源文件)都放在同一个目录里面,所以我们需要将这些sourceSet组件重新映射到src目录下。
注意:setRoot()方法将移动整个组件(包括它的子文件夹)到一个新的文件夹。示例中将会移动scr/androidTest/*到tests/*下。
以上这些是Android特有的,如果配置在Java的sourceSets里面将不会有作用。

以上也是将旧构建系统项目迁移到新构建系统需要做的迁移工作。


3.3 Build Tasks(构建任务)


3.3.1 General Tasks(通用任务)


添加一个插件到构建文件中将会自动创建一系列构建任务(build tasks)去执行(注:gradle属于任务驱动型构建工具,它的构建过程是基于Task的)。Java plugin和Android plugin都会创建以下task:
    * assemble:这个task将会组合项目的所有输出。
    * check:这个task将会执行所有检查。
    * build:这个task将会执行assemble和check两个task的所有工作
    * clean:这个task将会清空项目的输出。
实际上assemble,check,build这三个task不做任何事情。它们只是一个Task标志,用来告诉android plugin添加实际需要执行的task去完成这些工作。

这就允许你去调用相同的task,而不需要考虑当前是什么类型的项目,或者当前项目添加了什么plugin。
例如,添加了findbugs plugin将会创建一个新的task并且让check task依赖于这个新的task。当check task被调用的时候,这个新的task将会先被调用。

在命令行环境中,你可以执行以下命令来获取更多高级别的task:

gradle tasks

查看所有task列表和它们之间的依赖关系可以执行以下命令:
gradle tasks --all

注意:Gradle会自动监视一个task声明的所有输入和输出。
两次执行build task并且期间项目没有任何改动,gradle将会使用UP-TO-DATE通知所有task。这意味着第二次build执行的时候不会请求任何task执行。这允许task之间互相依赖,而不会导致不需要的构建请求被执行。

3.3.2 Java project tasks(Java项目的Task)


Java plugin主要创建了两个task,依赖于main task(一个标识性的task):
    * assemble
        * jar:
这个task创建所有输出
    * check
        * test:
这个task执行所有的测试。
jar task自身直接或者间接依赖于其他task:classes task将会被调用于编译java源码。
testClasses task用于编译测试,但是它很少被调用,因为test task依赖于它(类似于classes task)。

通常情况下,你只需要调用到assemble和check,不需要其他task。

你可以在Gradle文档中查看java plugin的全部task。

3.3.3 Android tasks


Android plugin使用相同的约定以兼容其他插件,并且附加了自己的标识性task,包括:
    * assemble:这个task用于组合项目中的所有输出。
    * check:这个task用于执行所有检查。
    * connectedCheck:这个task将会在一个指定的设备或者模拟器上执行检查,它们可以同时在所有连接的设备上执行。
    * deviceCheck:通过APIs连接远程设备来执行检查,这是在CL服务器上使用的。
    * build:这个task执行assemble和check的所有工作。
    * clean:这个task清空项目的所有输出。
这些新的标识性task是必须的,以保证能够在没有设备连接的情况下执行定期检查。
注意build task不依赖于deviceCheck或者connectedCheck。

一个Android项目至少拥有两个输出:debug APK(调试版APK)和release APK(发布版APK)。每一个输出都拥有自己的标识性task以便能够单独构建它们。
    * assemble:
        * assembleDebug
        * assembleRelease

它们都依赖于其它一些tasks以完成构建一个APK需要多个步骤。其中assemble task依赖于这两个task,所以执行assemble将会同时构建出两个APK。

小提示:gradle在命令行终端上支持骆驼命名法的task简称,例如,执行gradle aR命令等同于执行gradle assembleRelease。

check task也拥有自己的依赖:
    * check:
        * lint
    * connectedCheck:
        * connectedAndroidTest
        * connectedUiAutomatorTest(目前还没有应用到)
    * deviceCheck:
这个test依赖于test创建时,其它实现测试扩展点的插件。

最后,只要task能够被安装(那些要求签名的task),android plugin就会为所有构建类型(debug,release,test)安装或者卸载。

3.4 Basic Build Customization(基本的构建定制)


Android plugin提供了大量DSL用于直接从构建系统定制大部分事情。

3.4.1 Manifest entries (Manifest属性)


通过SDL可以配置一下manifest选项:
    * minSdkVersion
    * targetSdkVersion
    * versionName
    * packageName
    * package Name for the test application
    * Instrumentation test runner

例如:

android {
        compileSdkVersion 19

        buildToolsVersion "19.0.0"


        defaultConfig {
            versionCode 12

            versionName "2.0"

            minSdkVersion 16
            targetSdkVersion 16
        }
    }

在android元素中的defaultConfig元素中定义所有配置。

之前的Android Plugin版本使用packageName来配置manifest文件中的packageName属性。从0.11.0版本开始,你需要在build.gradle文件中使用applicationId来配置manifest文件中的packageName属性。
这是为了消除应用程序的packageName(也是程序的ID)和java包名所引起的混乱。

在构建文件中定义的强大之处在于它是动态的。
例如,可以从一个文件中或者其它自定义的逻辑代码中读取版本信息:
def computeVersionName() {
        ...
    }

    android {
        compileSdkVersion 19
        buildToolsVersion "19.0.0"

        defaultConfig {
            versionCode 12
            versionName computeVersionName()
            minSdkVersion 16
            targetSdkVersion 16
        }
    }

注意:不要使用与在给定范围内的getter方法可能引起冲突的方法名。例如,在defaultConfig{...}中调用getVersionName()将会自动调用defaultConfig.getVersionName()方法,你自定义的getVersionName()方法就被取代掉了。

如果一个属性没有使用DSL进行设置,一些默认的属性值将会被使用。以下表格是可能使用到的值:

Property Name Default value in DSL object Default value
versionCode     -1 value from manifest if present
versionName     null     value from manifest if present
minSdkVersion   -1 value from manifest if present
targetSdkVersion   -1 value from manifest if present
packageName     packageName     value from manifest if present
testPackageName null     app package name + “.test”
testInstrumentationRunner null     android.test.InstrumentationTestRunner
signingConfig     null     null    
proguardFile     N/A (set only) N/A (set only)
proguardFiles     N/A (set only) N/A (set only)

如果你在构建脚本中使用自定义代码逻辑请求这些属性,那么第二列的值将非常重要。例如,你可能会写:
if (android.defaultConfig.testInstrumentationRunner == null) {
        // assign a better default...
    }
如果这个值一直保持null,那么在构建执行期间将会实际替换成第三列的默认值。但是在DSL元素中并没有包含这个默认值,所以,你无法查询到这个值。
除非是真的需要,这是为了预防解析应用的manifest文件。
    

3.4.2 Build Types(构建类型)


默认情况下,Android Plugin会自动给项目设置同时构建应用程序的debug和release版本。
两个版本之间的不同主要围绕着能否在一个安全设备上调试,以及APK如何签名。

Debug版本采用使用通用的name/password键值对自动创建的数字证书进行签名,以防止构建过程中出现请求信息。Release版本在构建过程中没有签名,需要稍后再签名。

这些配置通过一个BuildType对象来配置。默认情况下,这两个实例都会被创建,分别是一个debug版本和一个release版本。

Android plugin允许像创建其他构建类型一样定制debug和release实例。这需要在buildTypes的DSL容器中配置:
android {
        buildTypes {
            debug {
                applicationIdSuffix ".debug"

            }

            jnidebug.initWith(buildTypes.debug)
            jnidebug {
                packageNameSuffix ".jnidebug"
                jnidebugBuild true
            }
        }
    }
   
以上代码片段实现了以下功能:
    * 配置默认的debug构建类型:将debug版本的包名设置为<app package>.debug以便能够同时在一台设备上安装debug和release版本的apk。
    * 创建了一个名为“jnidebug”的新构建类型,并且这个构建类型是debug构建类型的一个副本。
    * 继续配置jnidebug构建类型,允许使用JNI组件,并且也添加了不一样的包名后缀。
    
创建一个新的构建类型就是简单的在buildType标签下添加一个新的元素,并且可以使用initWith()或者直接使用闭包来配置它。

以下是一些可能使用到的属性和默认值:

Property name Default values for debug Default values for release / other
debuggable     debuggable     false
jniDebugBuild     false false
renderscriptDebugBuild   false false
renderscriptOptimLevel   3 3
packageNameSuffix     null null
versionNameSuffix     null null
signingConfig     android.signingConfigs.debug null
zipAlign     false     true
runProguard     false false
proguardFile     N/A (set only) N/A (set only)
proguardFiles     N/A (set only) N/A (set only)


除了以上属性之外,Build Type还会受项目源码和资源影响:
对于每一个Build Type都会自动创建一个匹配的sourceSet。默认的路径为:
src/<buildtypename>/
这意味着BuildType名称不能是main或者androidTest(因为这两个是由plugin强制实现的),并且他们互相之间都必须是唯一的。

跟其他sourceSet设置一样,Build Type的source set路径可以重新被定向:
android {
        sourceSets.jnidebug.setRoot(''foo/jnidebug'')
    }

另外,每一个Build Type都会创建一个新的assemble<BuildTypeName>任务。

assembleDebug和assembleRelease两个Task在上面已经提到过,这里要讲这两个Task从哪里被创建。当debug和release构建类型被预创建的时候,它们的tasks就会自动创建对应的这个两个Task。

上面提到的build.gradle代码片段中也会实现assembleJnidebug task,并且assemble会像依赖于assembleDebug和assembleRelease一样依赖于assembleJnidebug。

提示:你可以在终端下输入gradle aJ去运行assembleJnidebug task。

可能会使用到的情况:
    * release模式不需要,只有debug模式下才使用到的权限
    * 自定义的debug实现
    * 为debug模式使用不同的资源(例如当资源的值由绑定的证书决定)

BuildType的代码和资源通过以下方式被使用:
    * manifest将被混合进app的manifest
    * 代码行为只是另一个资源文件夹
    * 资源将叠加到main的资源中,并替换已存在的资源。


3.4.3 signing configurations(签名配置)


对一个应用程序签名需要以下:
    * 一个Keystory
    * 一个keystory密码
    * 一个key的别名
    * 一个key的密码
    * 存储类型

位置,键名,两个密码,还有存储类型一起形成了签名配置。
    
默认情况下,debug被配置成使用一个debug keystory。debug keystory使用了默认的密码和默认key及默认的key密码。
debug keystory的位置在$HOME/.android/debug.keystroe,如果对应位置不存在这个文件将会自动创建一个。

debug构建类型会自动使用debug签名配置。

可以创建其他配置或者自定义内建的默认配置。通过signingConfigs这个DSL容器来配置:
android {
        signingConfigs {
            debug {
                storeFile file("debug.keystore")
            }

            myConfig {
                storeFile file("other.keystore")
                storePassword "android"
                keyAlias "androiddebugkey"
                keyPassword "android"
            }
        }

        buildTypes {
            foo {
                debuggable true
                jniDebugBuild true
                signingConfig signingConfigs.myConfig
            }
        }
    }
以上代码片段修改debug keystory的路径到项目的根目录下。在这个例子中,这将自动影响其他使用到debug构建类型的构建类型。

这里也创建了一个新的Single Config(签名配置)和一个使用这个新签名配置的新的Build Type(构建类型)。

注意:只有默认路径下的debug keystory不存在时会被自动创建。更改debug keystory的路径并不会自动在新路径下创建debug keystory。如果创建一个新的不同名字的SignConfig,但是使用默认的debug keystore路径来创建一个非默认的名字的SigningConing,那么还是会在默认路径下创建debug keystory。换句话说,会不会自动创建是根据keystory的路径来判断,而不是配置的名称。

注意:虽然经常使用项目根目录的相对路径作为keystore的路径,但是也可以使用绝对路径,尽管这并不推荐(除了自动创建出来的debug keystore)。

注意:如果你将这些文件添加到版本控制工具中,你可能不希望将密码直接写到这些文件中。下面Stack Overflow链接提供从控制台或者环境变量中获取密码的方法:
http://stackoverflow.com/questions/18328730/how-to-create-a-release-signed-apk-file-using-gradle
我们以后还会在这个指南中添加更多的详细信息。

3.4.4 Running Proguard(运行 Proguard)


从Gradle Plugin for ProGuard version 4.10之后就开始支持ProGuard。ProGuard插件是自动添加进来的。如果Build Type的runProguard属性被设置为true,对应的task将会自动创建。
android {
    buildTypes {
        release {
            runProguard true
            proguardFile getDefaultProguardFile(''proguard-android.txt'')
        }
    }

    productFlavors {
        flavor1 {
        }
        flavor2 {
            proguardFile ''some-other-rules.txt''
        }

    }
}

发布版本将会使用它的Build Type中声明的规则文件,product flavor(定制的产品版本)将会使用对应flavor中声明的规则文件。

这里有两个默认的规则文件:
    * proguard-android.txt
    * proguard-android-optimize.txt

这两个文件都在SDK的路径下。使用getDefaultProguardFile()可以获取这些文件的完整路径。它们除了是否要进行优化之外,其它都是相同的。

Android Gradle Plugin指南(六)——高级构建定制

Android Gradle Plugin指南(六)——高级构建定制

原文地址:http://tools.android.com/tech-docs/new-build-system/user-guide#TOC-Advanced-Build-Customization


7、 Advanced Build Customization(高级构建定制)


7.1 Build options(构建选项)


7.1.1 Java Compilation options(Java编译选项)


android {
        compileOptions {
            sourceCompatibility = "1.6"
            targetCompatibility = "1.6"
        }
    }

默认值是“1.6”。这个设置将影响所有task编译Java源代码。


7.1.2 aapt options(aapt选项)


android {
        aaptOptions {
            noCompress ''foo'', ''bar''
            ignoreAssetsPattern "!.svn:!.git:!.ds_store:!*.scc:.*:<dir>_*:!CVS:!thumbs.db:!picasa.ini:!*~"
        }
    }

这将影响所有使用aapt的task。


7.1.3 dex options(dex选项)


android {
        dexOptions {
            incremental false

            preDexLibraries = false

            jumboMode = false

        }
    }

这将应用所有使用dex的task。


7.2 Manipulation tasks(操作task)


基础Java项目有一组有限的task用于互相处理生成一个输出。

classes是一个编译Java源代码的task。可以在build.gradle文件中通过脚本很容易使用classes。这是project.tasks.classes的缩写。


在Android项目中,相比之下这就有点复杂。因为Android项目中会有大量相同的task,并且它们的名字基于Build Types和Product Flavor生成。


为了解决这个问题,android对象有两个属性:

    * applicationVariants(只适用于app plugin)

    * libraryVariants(只适用于library plugin)

    * testVariants(两个plugin都适用)

这三个都会分别返回一个ApplicationVariant、LibraryVariant和TestVariant对象的DomainObjectCollection


注意使用这三个collection中的其中一个都会触发生成所有对应的task。这意味着使用collection之后不需要更改配置。


DomainObjectCollection可以直接访问所有对象,或者通过过滤器进行筛选。

android.applicationVariants.each { variant ->
        ....
    }

这三个variant类都共享下面的属性:

属性名 属性类型 说明
name String Variant的名字,必须是唯一的。
description String Variant的描述说明。
dirName String Variant的子文件夹名,必须也是唯一的。可能也会有不止一个子文件夹,例如“debug/flavor1”
baseName String Variant输出的基础名字,必须唯一。
outputFile File Variant的输出,这是一个可读可写的属性。
processManifest ProcessManifest 处理Manifest的task。
aidlCompile AidlCompile 编译AIDL文件的task。
renderscriptCompile RenderscriptCompile 编译Renderscript文件的task。
mergeResources MergeResources 混合资源文件的task。
mergeAssets MergeAssets 混合asset的task。
processResources ProcessAndroidResources 处理并编译资源文件的task。
generateBuildConfig GenerateBuildConfig 生成BuildConfig类的task。
javaCompile JavaCompile 编译Java源代码的task。
processJavaResources Copy 处理Java资源的task。
assemble DefaultTask Variant的标志性assemble task。

ApplicationVariant类还有以下附加属性:

属性名 属性类型 说明
buildType BuildType Variant的BuildType。
productFlavors List<ProductFlavor> Variant的ProductFlavor。一般不为空但也允许空值。
mergedFlavor ProductFlavor android.defaultConfig和variant.productFlavors的合并。
signingConfig SigningConfig Variant使用的SigningConfig对象。
isSigningReady boolean 如果是true则表明这个Variant已经具备了所有需要签名的信息。
testVariant BuildVariant 将会测试这个Variant的TestVariant。
dex Dex 将代码打包成dex的task。如果这个Variant是个库,这个值可以为空。
packageApplication PackageApplication 打包最终APK的task。如果这个Variant是个库,这个值可以为空。
zipAlign ZipAlign zip压缩APK的task。如果这个Variant是个库或者APK不能被签名,这个值可以为空。
install DefaultTask 负责安装的task,不能为空。
uninstall DefaultTask 负责卸载的task。

 LibraryVariant类还有以下附加属性:

属性名 属性类型 说明
buildType BuildType Variant的BuildType.
mergedFlavor ProductFlavor The defaultConfig values
testVariant BuildVariant 用于测试这个Variant。
packageLibrary Zip 用于打包库项目的AAR文件。如果是个库项目,这个值不能为空。

TestVariant类还有以下属性:

属性名 属性值 说明
buildType BuildType Variant的Build Type。
productFlavors List<ProductFlavor> Variant的ProductFlavor。一般不为空但也允许空值。
mergedFlavor ProductFlavor android.defaultConfig和variant.productFlavors的合并。
signingConfig SigningConfig Variant使用的SigningConfig对象。
isSigningReady boolean 如果是true则表明这个Variant已经具备了所有需要签名的信息。
testedVariant BaseVariant TestVariant测试的BaseVariant
dex Dex 将代码打包成dex的task。如果这个Variant是个库,这个值可以为空。
packageApplication PackageApplication 打包最终APK的task。如果这个Variant是个库,这个值可以为空。
zipAlign ZipAlign zip压缩APK的task。如果这个Variant是个库或者APK不能被签名,这个值可以为空。
install DefaultTask 负责安装的task,不能为空。
uninstall DefaultTask 负责卸载的task。
connectedAndroidTest DefaultTask 在连接设备上行执行Android测试的task。
providerAndroidTest DefaultTask 使用扩展API执行Android测试的task。

 Android task特有类型的API:

    * ProcessManifest

        * File manifestOutputFile

    * AidlCompile

        * File sourceOutputDir

    * RenderscriptCompile

        * File sourceOutputDir

        * File resOutputDir

    * MergeResources

        * File outputDir

    * MergeAssets

        * File outputDir

    * ProcessAndroidResources

        * File manifestFile

        * File resDir

        * File assetsDir

        * File sourceOutputDir

        * File textSymbolOutputDir

        * File packageOutputFile

        * File proguardOutputFile

    * GenerateBuildConfig

        * File sourceOutputDir

    * Dex

        * File outputFolder

    * PackageApplication

        * File resourceFile

        * File dexFile

        * File javaResourceDir

        * File jniDir

        * File outputFile

            * 直接在Variant对象中使用“outputFile”可以改变最终的输出文件夹。

    * ZipAlign

        * File inputFile

        * File outputFile

            * 直接在Variant对象中使用“outputFile”可以改变最终的输出文件夹。


每个task类型的API由于Gradle的工作方式和Android plugin的配置方式而受到限制。

首先,Gradle意味着拥有的task只能配置输入输出的路径和一些可能使用的选项标识。因此,task只能定义一些输入或者输出。


其次,这里面大多数task的输入都不是单一的,一般都混合了sourceSet、Build Type和Product Flavor中的值。为了保持构建文件的简单和可读性,目标是要让开发者通过DSL语言修改这些对象来配饰构建的过程,而不是深入修改输入和task的选项。


另外需要注意,除了ZipAlign这个task类型,其它所有类型都要求设置私有数据来让它们运行。这意味着不可能自动创建这些类型的新task实例。


这些API也可能会被更改。一般来说,目前的API是围绕着给定task的输入和输出入口来添加额外的处理(如果需要的时候)。欢迎反馈意见,特别是那些没有预见过的需求。


对于Gradle的task(DefaultTask,JavaCompile,Copy,Zip),请参考Gradle文档。


7.3 BuildType and Product Flavor property reference(BuildType和Product Flavor属性参考)


coming soon。。。。= =
对于Gradle的task(DefaultTask,JavaCompile,Copy,Zip),请参考Gradle文档。

7.4 Using sourceCompatibility 1.7(使用(JDK)1.7版本的sourceCompatibility)


使用Android KitKat(19版本的buildTools)就可以使用diamond operator,multi-catch,switch中使用字符串,try with resource等等(译注:都是JDK7的一些新特性,详情请参考JDK7文档)。设置使用1.7版本,需要修改你的构建文件:
android {
    compileSdkVersion 19
    buildToolsVersion "19.0.0"

    defaultConfig {
        minSdkVersion 7
        targetSdkVersion 19
    }

    compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_7
        targetCompatibility JavaVersion.VERSION_1_7
    }
}

注意:你可以将minSdkVersion的值设置为19之前的版本,只是你只能使用除了try with resources之外的其它新语言特性。如果你想要使用try with resources特性,你就需要把minSdkVersion也设置为19。

你同样也需要确认Gradle使用1.7或者更高版本的JDK(Android Gradle plugin也需要0.6.1或者更高的版本)。

android gradle 和 gradle plugin

android gradle 和 gradle plugin

android gradle 和 gradle plugin

1、安装完 AS3.5.2 创建完项目一运行,报了如下错误

Error:Could not find com.android.tools.build:gradle:4.1. Searched in
the following locations:
file:/C:/Program Files/Android/Android Studio/gradle/m2repository/com/android/tools/build/gradle/4.1/gradle-4.1.pom file:/C:/Program Files/Android/Android Studio/gradle/m2repository/com/android/tools/build/gradle/4.1/gradle-4.1.jar https://repo1.maven.org/maven2/com/android/tools/build/gradle/4.1/gradle-4.1.pom https://repo1.maven.org/maven2/com/android/tools/build/gradle/4.1/gradle-4.1.jar https://littlefogcat.top/example/com/android/tools/build/gradle/4.1

问题分析:

首先想到的是去看看我的grid : File =>Settings =>gradle 
发现我gradle的是存在的
那么去看看项目的gridle版本:File=>project structure =>project 查看,发现我的
Android Gradle Plugin Version 版本和我的插件版本都是4.1
按理说因该没问题的啊,
但是实际是这样的么?
回到问题本身,再去看看错误提示信息没有找到C:/Program Files/Android/Android Studio/gradle/m2repository/com/android/tools/build/gradle/4.1/gradle-4.1.jar
再去他给的下载地址去看看,发现目前为止最新版本的gradle是2.3.0
好吧,那就把我的gradle plugin版本改为2.3.0

问题解决:

把我的gradle plugin版本改为2.3.0

2、新问题来了:

org.gradle.api.ProjectConfigurationException: A problem occurred configuring project '':app''.
    at org.gradle.configuration.project.LifecycleProjectEvaluator.addConfigurationFailure(LifecycleProjectEvaluator.java:94)
    at org.gradle.configuration.project.LifecycleProjectEvaluator.doConfigure(LifecycleProjectEvaluator.java:72)
    at org.gradle.configuration.project.LifecycleProjectEvaluator.access$000(LifecycleProjectEvaluator.java:33)
    at org.gradle.configuration.project.LifecycleProjectEvaluator$1.execute(LifecycleProjectEvaluator.java:53)
    at org.gradle.configuration.project.LifecycleProjectEvaluator$1.execute(LifecycleProjectEvaluator.java:50)
    at org.gradle.internal.Transformers$4.transform(Transformers.java:169)
    at org.gradle.internal.progress.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:106)
    at org.gradle.internal.progress.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:61)
    at org.gradle.configuration.project.LifecycleProjectEvaluator.evaluate(LifecycleProjectEvaluator.java:50)
    at org.gradle.api.internal.project.DefaultProject.evaluate(DefaultProject.java:648)
    at org.gradle.api.internal.project.DefaultProject.evaluate(DefaultProject.java:126)
    at org.gradle.execution.TaskPathProjectEvaluator.configure(TaskPathProjectEvaluator.java:35)
    at org.gradle.execution.TaskPathProjectEvaluator.configureHierarchy(TaskPathProjectEvaluator.java:62)
    at org.gradle.configuration.DefaultBuildConfigurer.configure(DefaultBuildConfigurer.java:38)
    at org.gradle.initialization.DefaultGradleLauncher$ConfigureBuildAction.execute(DefaultGradleLauncher.java:207)
    at org.gradle.initialization.DefaultGradleLauncher$ConfigureBuildAction.execute(DefaultGradleLauncher.java:204)
    at org.gradle.internal.Transformers$4.transform(Transformers.java:169)
    at org.gradle.internal.progress.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:106)
    at org.gradle.internal.progress.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:56)
    at org.gradle.initialization.DefaultGradleLauncher.doBuildStages(DefaultGradleLauncher.java:146)
    at org.gradle.initialization.DefaultGradleLauncher.doBuild(DefaultGradleLauncher.java:112)
    at org.gradle.initialization.DefaultGradleLauncher.getBuildAnalysis(DefaultGradleLauncher.java:100)
    at org.gradle.launcher.exec.GradleBuildController.configure(GradleBuildController.java:74)
    at org.gradle.tooling.internal.provider.runner.ClientProvidedBuildActionRunner.run(ClientProvidedBuildActionRunner.java:65)
    at org.gradle.launcher.exec.ChainingBuildActionRunner.run(ChainingBuildActionRunner.java:35)
    at org.gradle.tooling.internal.provider.runner.RunAsBuildOperationBuildActionRunner$1.execute(RunAsBuildOperationBuildActionRunner.java:43)
    at org.gradle.tooling.internal.provider.runner.RunAsBuildOperationBuildActionRunner$1.execute(RunAsBuildOperationBuildActionRunner.java:40)
    at org.gradle.internal.Transformers$4.transform(Transformers.java:169)
    at org.gradle.internal.progress.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:106)
    at org.gradle.internal.progress.DefaultBuildOperationExecutor.run(DefaultBuildOperationExecutor.java:56)
    at org.gradle.tooling.internal.provider.runner.RunAsBuildOperationBuildActionRunner.run(RunAsBuildOperationBuildActionRunner.java:40)
    at org.gradle.tooling.internal.provider.runner.SubscribableBuildActionRunner.run(SubscribableBuildActionRunner.java:88)
    at org.gradle.launcher.exec.ChainingBuildActionRunner.run(ChainingBuildActionRunner.java:35)
    at org.gradle.launcher.exec.InProcessBuildActionExecuter.execute(InProcessBuildActionExecuter.java:41)
    at org.gradle.launcher.exec.InProcessBuildActionExecuter.execute(InProcessBuildActionExecuter.java:26)
    at org.gradle.tooling.internal.provider.ContinuousBuildActionExecuter.execute(ContinuousBuildActionExecuter.java:75)
    at org.gradle.tooling.internal.provider.ContinuousBuildActionExecuter.execute(ContinuousBuildActionExecuter.java:49)
    at org.gradle.tooling.internal.provider.ServicesSetupBuildActionExecuter.execute(ServicesSetupBuildActionExecuter.java:49)
    at org.gradle.tooling.internal.provider.ServicesSetupBuildActionExecuter.execute(ServicesSetupBuildActionExecuter.java:31)
    at org.gradle.launcher.daemon.server.exec.ExecuteBuild.doBuild(ExecuteBuild.java:67)
    at org.gradle.launcher.daemon.server.exec.BuildCommandOnly.execute(BuildCommandOnly.java:36)
    at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:120)
    at org.gradle.launcher.daemon.server.exec.WatchForDisconnection.execute(WatchForDisconnection.java:37)
    at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:120)
    at org.gradle.launcher.daemon.server.exec.ResetDeprecationLogger.execute(ResetDeprecationLogger.java:26)
    at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:120)
    at org.gradle.launcher.daemon.server.exec.RequestStopIfSingleUsedDaemon.execute(RequestStopIfSingleUsedDaemon.java:34)
    at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:120)
    at org.gradle.launcher.daemon.server.exec.ForwardClientInput$2.call(ForwardClientInput.java:74)
    at org.gradle.launcher.daemon.server.exec.ForwardClientInput$2.call(ForwardClientInput.java:72)
    at org.gradle.util.Swapper.swap(Swapper.java:38)
    at org.gradle.launcher.daemon.server.exec.ForwardClientInput.execute(ForwardClientInput.java:72)
    at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:120)
    at org.gradle.launcher.daemon.server.exec.LogAndCheckHealth.execute(LogAndCheckHealth.java:55)
    at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:120)
    at org.gradle.launcher.daemon.server.exec.LogToClient.doBuild(LogToClient.java:60)
    at org.gradle.launcher.daemon.server.exec.BuildCommandOnly.execute(BuildCommandOnly.java:36)
    at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:120)
    at org.gradle.launcher.daemon.server.exec.EstablishBuildEnvironment.doBuild(EstablishBuildEnvironment.java:72)
    at org.gradle.launcher.daemon.server.exec.BuildCommandOnly.execute(BuildCommandOnly.java:36)
    at org.gradle.launcher.daemon.server.api.DaemonCommandExecution.proceed(DaemonCommandExecution.java:120)
    at org.gradle.launcher.daemon.server.exec.StartBuildOrRespondWithBusy$1.run(StartBuildOrRespondWithBusy.java:50)
    at org.gradle.launcher.daemon.server.DaemonStateCoordinator$1.run(DaemonStateCoordinator.java:297)
    at org.gradle.internal.concurrent.ExecutorPolicy$CatchAndRecordFailures.onExecute(ExecutorPolicy.java:63)
    at org.gradle.internal.concurrent.StoppableExecutorImpl$1.run(StoppableExecutorImpl.java:46)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
    at java.lang.Thread.run(Thread.java:748)
Caused by: org.gradle.api.GradleScriptException: A problem occurred evaluating project '':app''.
    at org.gradle.groovy.scripts.internal.DefaultScriptRunnerFactory$ScriptRunnerImpl.run(DefaultScriptRunnerFactory.java:92)
    at org.gradle.configuration.DefaultScriptPluginFactory$ScriptPluginImpl$2.run(DefaultScriptPluginFactory.java:176)
    at org.gradle.configuration.ProjectScriptTarget.addConfiguration(ProjectScriptTarget.java:77)
    at org.gradle.configuration.DefaultScriptPluginFactory$ScriptPluginImpl.apply(DefaultScriptPluginFactory.java:181)
    at org.gradle.configuration.project.BuildScriptProcessor.execute(BuildScriptProcessor.java:39)
    at org.gradle.configuration.project.BuildScriptProcessor.execute(BuildScriptProcessor.java:26)
    at org.gradle.configuration.project.ConfigureActionsProjectEvaluator.evaluate(ConfigureActionsProjectEvaluator.java:34)
    at org.gradle.configuration.project.LifecycleProjectEvaluator.doConfigure(LifecycleProjectEvaluator.java:70)
    ... 66 more
Caused by: org.gradle.internal.metaobject.AbstractDynamicObject$CustomMessageMissingMethodException: Could not find method implementation() for arguments [directory ''libs''] on object of type org.gradle.api.internal.artifacts.dsl.dependencies.DefaultDependencyHandler.
    at org.gradle.internal.metaobject.AbstractDynamicObject.methodMissingException(AbstractDynamicObject.java:182)
    at org.gradle.internal.metaobject.ConfigureDelegate.invokeMethod(ConfigureDelegate.java:89)
    at org.codehaus.groovy.runtime.metaclass.ClosureMetaClass.invokeOnDelegationObjects(ClosureMetaClass.java:430)
    at org.codehaus.groovy.runtime.metaclass.ClosureMetaClass.invokeMethod(ClosureMetaClass.java:369)
    at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1027)
    at org.codehaus.groovy.runtime.callsite.PogoMetaClassSite.callCurrent(PogoMetaClassSite.java:69)
    at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCallCurrent(CallSiteArray.java:52)
    at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callCurrent(AbstractCallSite.java:154)
    at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callCurrent(AbstractCallSite.java:166)
    at build_cwcqry1dtacujy4w7qkivl3cy$_run_closure2.doCall(D:\Android\UIautoApplication\app\build.gradle:27)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:93)
    at groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:325)
    at org.codehaus.groovy.runtime.metaclass.ClosureMetaClass.invokeMethod(ClosureMetaClass.java:294)
    at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1027)
    at groovy.lang.Closure.call(Closure.java:414)
    at groovy.lang.Closure.call(Closure.java:430)
    at org.gradle.api.internal.ClosureBackedAction.execute(ClosureBackedAction.java:71)
    at org.gradle.util.ConfigureUtil.configureTarget(ConfigureUtil.java:160)
    at org.gradle.util.ConfigureUtil.configure(ConfigureUtil.java:106)
    at org.gradle.api.internal.project.DefaultProject.dependencies(DefaultProject.java:1111)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:93)
    at groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:325)
    at org.gradle.internal.metaobject.BeanDynamicObject$MetaClassAdapter.invokeMethod(BeanDynamicObject.java:464)
    at org.gradle.internal.metaobject.BeanDynamicObject.invokeMethod(BeanDynamicObject.java:176)
    at org.gradle.internal.metaobject.CompositeDynamicObject.invokeMethod(CompositeDynamicObject.java:96)
    at org.gradle.internal.metaobject.MixInClosurePropertiesAsMethodsDynamicObject.invokeMethod(MixInClosurePropertiesAsMethodsDynamicObject.java:30)
    at org.gradle.groovy.scripts.BasicScript.invokeMethod(BasicScript.java:107)
    at org.gradle.groovy.scripts.BasicScript.methodMissing(BasicScript.java:116)
    at sun.reflect.GeneratedMethodAccessor25.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:93)
    at groovy.lang.MetaClassImpl.invokeMissingMethod(MetaClassImpl.java:944)
    at groovy.lang.MetaClassImpl.invokePropertyOrMissing(MetaClassImpl.java:1267)
    at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1220)
    at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1027)
    at org.codehaus.groovy.runtime.callsite.PogoMetaClassSite.callCurrent(PogoMetaClassSite.java:69)
    at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCallCurrent(CallSiteArray.java:52)
    at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callCurrent(AbstractCallSite.java:154)
    at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callCurrent(AbstractCallSite.java:166)
    at build_cwcqry1dtacujy4w7qkivl3cy.run(D:\Android\UIautoApplication\app\build.gradle:26)
    at org.gradle.groovy.scripts.internal.DefaultScriptRunnerFactory$ScriptRunnerImpl.run(DefaultScriptRunnerFactory.java:90)
    ... 73 more

问题分析:gradle 版本过低,不支持 c.... 需要升级到 3.0 以上的版本

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 



 

关于Android Gradle Plugin指南一——简介的问题就给大家分享到这里,感谢你花时间阅读本站内容,更多关于Android Gradle Plugin指南(三)——依赖关系、android库和多项目配置、Android Gradle Plugin指南(二)——基本项目、Android Gradle Plugin指南(六)——高级构建定制、android gradle 和 gradle plugin等相关知识的信息别忘了在本站进行查找喔。

本文标签: