精华内容
下载资源
问答
  • 第6章 Gradle守护进程原文 目录6.1 启用守护进程 6.2 停止现有的守护进程 6.3 常问问题 6.4 何时不应该使用Gradle守护进程? 6.5 工具和IDE 6.6 Gradle Daemon如何更快地构建?From Wikipedia…守护进程是一...

    第6章 Gradle守护进程

    原文
    欢迎关注公众号:Glide風
    这里写图片描述
    目录

    6.1 启用守护进程
    6.2 停止现有的守护进程
    6.3 常问问题
    6.4 何时不应该使用Gradle守护进程?
    6.5 工具和IDE
    6.6 Gradle Daemon如何更快地构建?

    From Wikipedia…

    守护进程是一种作为后台进程运行的计算机程序,而不是由交互式用户直接控制。

    Gradle在Java虚拟机(JVM)上运行,并使用一些支持库,这些库需要一定的初始化时间。因此,有时候看起来有点慢。解决这个问题的方法是启用Gradle Daemon(Daemon:一个长期的后台进程,比其他情况下执行你的构建要快得多)。我们通过避免昂贵的引导过程以及利用缓存来实现这一点,将有关项目的数据保存在内存中。运行Gradle与守护进程构建没有区别,进行简单地配置后无论你是否要使用它 都将由Gradle自行的处理。

    6.1 启用守护进程

    Gradle Daemon在默认情况下是不启用的,但是我们建议开发者的设备始终启用它(但是对于持续集成服务器,将其禁用)。启用守护进程有几种方法,但最常见的方法是添加该行

    org.gradle.daemon =true
    

    到文件/.gradle/gradle.properties下进行配置, 所在位置取决于您的系统,通常如下:

    • C:\Users\ (Windows Vista&7+
    • /Users/ (Mac OS X)
    • /home/ (Linux)

    注:<USER_HOME>为当前用户的主目录,比如:C:\Users\Administrator那么这个<USER_HOME>指的就是Administrator。

    如果该文件不存在,只需使用文本编辑器创建。您可以在下面的FAQ中找到启用(和禁用)守护进程的其他方法的详细信息。该部分还包含关于守护进程如何工作的更多详细信息。

    一旦以这种方式全局启用了守护进程,不管特定构建使用的Gradle版本如何,所有的构建速度都将提升。

    6.2 停止现有的守护进程

    如前所述,守护进程是一个后台进程。但是,您不需要担心该后台进程对性能的影响,每个守护进程在三小时不活跃的情况下会自行停止。如果您因为一些原因想要停止守护进程,请使用该命令为:gradle –stop

    这将终止所有用于执行命令的相同版本的Gradle启动的守护进程。如果安装了Java Development Kit(JDK),则可以通过运行jps命令轻松验证守护程序是否已停止。您将看到任何正在运行的名为GradleDaemon的守护进程。

    6.3 常问问题

    6.3.1 启用Gradle Daemon的方法有哪些?
    有两种建议的方式来持续为一个环境启用守护进程:

    • 通过环境变量 - 将标志添加-Dorg.gradle.daemon=true到GRADLE_OPTS环境变量
    • 通过属性文件 -添加org.gradle.daemon=true到/gradle.properties文件
    请注意,<GRADLE_USER_HOME>默认为<USER_HOME>/.gradle,<USER_HOME>为当前用户的主目录,此位置可以通过-g和--gradle-user-home命令行开关以及GRADLE_USER_HOME环境变量和org.gradle.user.homeJVM系统属性进行配置。
    
    

    两种方法都有相同的效果,根据个人喜好来使用。大多数Gradle用户选择第二种方法,并将条目添加到用户gradle.properties文件。
    在Windows上,启用命令为:

    (if not exist "%USERPROFILE%/.gradle" mkdir "%USERPROFILE%/.gradle") && (echo org.gradle.daemon=true >> "%USERPROFILE%/.gradle/gradle.properties")  
    

    也就相当于,在C:\Users\.gradle文件下的gradle.properties(如果没有进行创建)中配置echo org.gradle.daemon=true
    在Linux环境下

    touch ~/.gradle/gradle.properties && echo "org.gradle.daemon=true" >> ~/.gradle/gradle.properties  

    一旦以这种方式为构建环境启用了守护进程,所有构建都将隐式使用Daemon。
    在个人的构建使用命令行界面时可以调用–daemon和–no-daemon命令行开关来启用和禁用守护程序。通常情况下,为一个环境(比如一个用户账号)启用守护进程会更方便,这样所有的版本都可以使用守护进程而不需要记住提供–daemon交换机

    6.3.2 我如何禁用Gradle守护进程?
    Gradle守护进程默认是不启用的。但是,一旦启用,有时需要禁用某些项目或某些构建时可以使用–no-daemon命令行开关进行强制禁用

    该命令行很少使用,但是在调试某些构建或者Gradle插件的问题时有时会很有用。考虑到构建环境,该命令行开关的优先级最高。

    6.3.3 如何抑制“please consider using the Gradle Daemon”消息?

    Gradle可能会在构建结束时发出警告,提示您使用Gradle守护程序。为了避免这个警告,你可以通过上面的方法来启用守护进程,或者明确禁用守护进程。你可以明确地通过使用禁用守护进程–no-daemon如上所述命令行开关,或着开启的方法之一,但org.gradle.daemon属性的值应为false,而不是true。

    由于不建议使用守护进程连续集成构建,所以如果CI环境变量存在,Gradle将不会发出消息。

    6.3.4 为什么我的机器上有多个守护进程?

    Gradle将创建一个新的守护进程有几个原因,而不是使用已经运行的守护进程。基本规则是:如果没有可用的空闲或兼容的守护进程,Gradle将启动一个新的守护进程。Gradle会杀死已经闲置3个小时以上的守护进程,所以你不必担心手动清理它们。


    一个空闲的守护进程是一个目前没有执行构建或做其他有用的工作。

    兼容
    一个兼容的守护进程是可以(或可以做到)满足所要求的构建环境的要求的守护进程。用于执行构建的Java运行时是构建环境的示例方面。另一个示例是构建运行时所需的一组JVM系统属性。

    守护进程可能无法满足所请求的构建环境的某些方面。如果守护程序正在Java 7环境下运行,但所请求的环境需要Java 8,则守护进程不兼容,必须启动另一个。而且,一旦JVM启动,Java运行时的某些属性就不能被改变。例如不能改变-Xmx1024m正在运行的JVM 的内存分配,默认文本编码,缺省语言环境等。

    “requested build environmen”通常是由构建客户端(例如Gradle命令行客户端,IDE等)环境以及通过命令行开关和设置明确构建的。有关如何指定和控制构建环境的详细信息,请参见第11章 “构建环境”

    以下JVM系统属性实际上是不可变的。如果请求的构建环境需要这些属性中的任何一个,并且当 Daemon的JVM所具有的属性值与其不同时,则守护程序将不兼容。

    • file.encoding
    • user.language
    • user.country
    • user.variant
    • java.io.tmpdir
    • javax.net.ssl.keyStore
    • javax.net.ssl.keyStorePassword
    • javax.net.ssl.keyStoreType
    • javax.net.ssl.trustStore中
    • javax.net.ssl.trustStorePassword中
    • javax.net.ssl.trustStoreType
    • com.sun.management.jmxremote

      以下由启动参数控制的JVM属性也是不可变的。所请求的构建环境和守护进程环境的相应属性必须完全匹配,以使守护进程兼容。

    • 最大堆大小(即-Xmx JVM参数)
    • 最小堆大小(即-Xms JVM参数)
    • 引导类路径(即-Xbootclasspath参数)
    • “断言”状态(即-ea参数)

    Gradle版本和编译环境的版本不同是另一个方面。守护进程耦合到特定的Gradle运行时,在使用不同Gradle版本的会话期间处理多个Gradle项目是拥有多个运行中的守护进程的常见原因。

    6.3.5 Daemon 使用多少内存,我可以给它多一点?
    如果请求的构建环境没有指定最大堆大小,守护进程将使用最多1GB的堆。它将使用您的JVM的默认最小堆大小。1GB对于大多数版本来说已经足够了。更大的构建与数百个子项目,大量的配置和源代码可能需要,或性能更好,更多的内存。

    要增加守护程序可以使用的内存量,请将相应的标志指定为所请求的生成环境的一部分。有关详细信息,请参阅第11章“构建环境 ”

    6.3.6 我怎样才能停止Daemon ?

    不活动3小时后,守护进程将自动终止。如果您希望在此之前停止守护进程,则可以通过操作系统终止进程或运行gradle –stop命令。该–stop开关使得Gradle请求运行该命令的相同Gradle版本的所有正在运行的Daemon进程自行终止。

    6.3.7 Daemon 有什么问题?
    在守护进程日益发展的过程中,相当大的工程努力已经使守护进程变得健壮,透明和不显眼。但是,守护进程偶尔会被损坏或耗尽。Gradle构建执行来自多个源的任意代码。虽然Gradle本身是专门为Daemon设计的并且经过严格测试,但是用户构建脚本和第三方插件可能会通过内存泄漏或全局状态损坏等缺陷来破坏守护进程的稳定性。

    通过运行不能正确释放资源的构建,也可能会破坏守护进程的稳定性(通常会构建环境)。在使用Microsoft Windows时,这是一个特别棘手的问题,因为它对读取或写入后无法关闭文件的程序宽容。

    Gradle会主动监视堆的使用情况,并尝试检测泄漏是否开始耗尽守护进程中可用的堆空间。当它检测到堆空间的问题时,Gradle守护进程将完成当前正在运行的构建,并在下一个构建中重新启动守护进程。此监视默认启用,但可以通过将org.gradle.daemon.performance.enable-monitoring系统属性设置为false 来禁用。

    如果怀疑守护进程变得不稳定,可能会被简单地杀死。回想一下,–no-daemon可以为构建指定开关,以防止使用守护进程。这对于诊断守护进程是否真的是问题的罪魁祸首可能是有用的

    6.4 何时不应该使用Gradle守护进程?

    建议在所有开发人员环境中使用守护进程并且不要启用用于持续集成的守护进程并构建服务器环境。

    守护进程使构建更快,当人坐在构建前面时,这一点尤为重要。对于CI构建,稳定性和可预测性是至关重要的。对于每个构建使用全新的运行时(即进程)更加可靠,因为运行时与以前的构建完全隔离

    6.5 工具和IDE
    IDE和其他工具用于与Gradle集成 的Gradle Tooling API(请参阅第13章,使用Tooling API嵌入Gradle)始终使用Gradle Daemon来执行构建。如果从内部执行Gradle构建,则您使用的是Gradle守护程序,无需为您的环境启用它。

    但是,除非您为您的环境明确启用了Gradle守护程序,否则命令行中的构建不会使用Gradle守护程序。

    6.6 Gradle Daemon如何更快地构建?
    Gradle守护进程是一个长期的构建过程。在构建之间,它等待下一个构建。这具有明显的好处,只需要将Gradle一次加载到多次构建中,而不是每次构建一次。这本身就是一个重要的性能优化,但这并不是停止的地方。

    现代JVM性能的一个重要部分是运行时代码优化。例如,HotSpot(Oracle提供的用作OpenJDK基础的JVM实现)在代码运行时对其进行优化。优化是渐进的而不是瞬时的。也就是说,代码在执行过程中被逐步优化,这意味着后续的构建可以更快地完成,纯粹是由于这个优化过程。HotSpot的实验表明,它需要5到10之间的构建优化来稳定。守护程序的第一次构建和第十次构建时间之间的差异可能相当大。

    守护进程还更有效的允许跨内存缓存。例如,构建所需的类(例如,插件,构建脚本)可以在构建之间保存在内存中。同样,Gradle可以维护内存缓存的构建数据,如任务输入和输出的散列,用于增量构建。

    6.6.1 潜在的未来增强

    目前,守护进程通过有效地支持内存缓存以及JVM优化器使代码更快,使构建更快。在未来的Gradle版本中,守护进程将变得更加智能,并且抢先进行工作。例如,假定构建即将运行,并且将需要新更改或添加的依赖关系,它可以在编译构建脚本之后立即开始下载依赖关系。

    Gradle Daemon还有很多其他的方法可以在未来的Gradle版本中实现更快的构建

    展开全文
  • 如果Gradle在编译类路径上找到注释处理器,它将 deactivates compile avoidance,这会对构建时间产生负面影响(Gradle 5.0及更高版本,忽略在 compile classpath 上找到的注释处理器)。 如果依赖项的JAR文件包含...
    Markdown版本笔记我的GitHub首页我的博客我的微信我的邮箱
    MyAndroidBlogsbaiqiantaobaiqiantaobqt20094baiqiantao@sina.com

    目录

    添加构建依赖项

    Add build dependencies

    Android Studio中的Gradle构建系统可以轻松地将外部二进制文件其他库模块作为依赖项包含在构建中。依赖项可以位于您的计算机上或远程存储库中,并且它们声明的任何传递依赖项[transitive dependencies]也会自动包含在内。

    此页面描述了如何在Android项目中使用依赖项,仅包含特定于Android的Gradle插件[specific to the Android plugin for Gradle]的行为和配置的详细信息。

    依赖类型

    Dependency types

    要向项目添加依赖项,请在build.gradle文件的dependencies块中指定依赖项配置。

    app模块的build.gradle文件包含以下三种不同类型的依赖项。

    本地库模块依赖:project

    Local library module dependency

    这声明了对名为“mylibrary”的Android库模块的依赖。此名称必须与在settings.gradle文件中定义为include的库名称匹配。构建应用程序时,构建系统会编译库模块并将生成的AAR文件打包到APK中。

    implementation project(":mylibrary") // 依赖当前目录下的本地库模块
    implementation project(":chat:mylibrary") //依赖当前目录下 chat 目录中的本地库模块

    本地二进制依赖:fileTree 和 files

    Local binary dependency

    Gradle在项目的 module_name/libs/ 目录(因为Gradle读取相对于build.gradle文件的路径)中声明对JAR文件的依赖。

    implementation fileTree(dir: 'libs', include: ['*.jar']) //指定目录或满足规则的所有文件
    implementation files('libs/foo.jar', 'libs/bar.jar') //指定单个文件

    远程二进制依赖

    Remote binary dependency

    示例中声明了对 com.example.android 命名空间组[namespace group]内 app-magic 库 12.3 版的依赖性。构建时,如果远程二进制依赖的库本地不存在,Gradle会在构建时从远程站点中下载

    implementation 'com.example.android:app-magic:12.3'  //简写
    implementation group: 'com.example.android', name: 'app-magic', version: '12.3'  //完整写法

    依赖配置类型

    Dependency configurations

    dependencies 块中,您可以使用几种不同的依赖项配置之一声明库依赖项。 每个依赖项配置都为Gradle提供了有关如何使用依赖项的不同说明。

    implementation、api、compile 的区别
    api 完全等同于 compile,两者没区别,你将所有的 compile 改成 api时完全没有错。

    implementation 这个指令的特点就是,对于使用了该命令编译的依赖,对该项目有依赖的项目将无法访问到使用该命令编译的依赖中的任何程序,也就是将该依赖隐藏在内部,而不对外部公开。换句话说就是,使用 implementation 指令的依赖只作用于当前的 module,而不会传递

    例如,有一个 module testsdk 依赖于 gson:implementation 'com.google.code.gson:gson:2.8.2'
    另一个 module app 依赖于 testsdk:implementation project(':testsdk')
    这时候,因为 testsdk 使用的是 implementation 指令来依赖 gson,所以 app 里边不能引用 gson。

    但是,如果 testsdk 使用的是 api 来引用 gson:api 'com.google.code.gson:gson:2.8.2'
    则与 Gradle3.0.0 之前的 compile 指令的效果完全一样,app 的 module 也可以引用 gson。

    implementation

    implementation 可以认为是功能精简的 compile

    Gradle将依赖项添加到编译类路径[compilation classpath],并将依赖项打包到构建输出[packages the dependency to the build output]。 但是,当您的模块配置 implementation 依赖项时,它让Gradle知道,您不希望模块在编译时将依赖项泄露给其他模块(意思是在编写代码时不可见)。也就是说,依赖性仅在运行时(运行时是没有分模块的概念的,所以当然可见啦)可用于其他模块。

    简单来说就是,使用 implementation 时,对于引用此模块的其他模块来说,在写代码时不可见(不能直接引用),但是在运行时可以通过反射方式调用。

    使用此依赖项配置而不是 api 或 compile,会减少构建时间,因为它减少了构建系统需要重新编译的模块数量。例如,如果一个 implementation 依赖项更改了其 API,那么Gradle只会重新编译依赖性和直接依赖于它的模块。大多数 app 和 test 模块都应使用此配置。

    api

    api 完全等同于 compile

    Gradle将依赖项添加到编译类路径并构建输出。当一个模块包含一个 api 依赖项时,它让Gradle知道,该模块想要将该依赖项传递给其他模块,以便它们在运行时和编译时都可用

    此配置的行为与 compile 类似,但您应谨慎使用它,通常,你应当仅在需要将依赖项传递给上游使用者时使用。这是因为,如果 api 依赖项更改其外部 API,Gradle 在重新编译时将重新编译有权访问该依赖项的所有模块。因此,拥有大量的 api 依赖项会显著增加构建时间。除非您希望将依赖项的 API 公开给单独的模块,否则模块应该使用 implementation 依赖项。

    compileOnly

    compileOnly 与废弃的 provided 完全一样

    Gradle仅将依赖项添加到编译类路径,即,它不会添加到构建输出中

    这在以下情况非常有用:您想创建一个 Android 模块,并且在编译期间需要依赖项,但在运行时其存在是可选的

    如果使用此配置,则库模块必须包含运行时条件[runtime condition]以检查依赖项是否可用,然后优雅的更改其行为,以便在未提供时仍可正常运行。这有助于通过,不添加不重要的瞬态[transient]依赖项,来减小最终APK的大小。

    注意:经测试发现,compileOnly不能传递依赖。

    runtimeOnly

    runtimeOnly 与废弃的 apk 完全一样

    Gradle仅将依赖项添加到构建输出,以便在运行时使用。也就是说,它不会添加到编译类路径中

    annotationProcessor

    annotationProcessor 可以认为是用于特定场景的 compile

    要添加对作为注释处理器的库的依赖关系,必须使用 annotationProcessor 配置将其添加到注释处理器 classpath。这是因为使用此配置可以通过将 compile classpath 与 annotationProcessor classpath 分开来提高构建性能

    如果Gradle在编译类路径上找到注释处理器,它将 deactivates compile avoidance,这会对构建时间产生负面影响(Gradle 5.0及更高版本,忽略在 compile classpath 上找到的注释处理器)。

    如果依赖项的JAR文件包含以下文件,则 Android Gradle Plugin 假定其是注释处理器,:

    META-INF/services/javax.annotation.processing.Processor

    如果插件检测到编译类路径上的注释处理器,则会产生构建错误。

    lintChecks

    Use this configuration to include lint checks you want Gradle to execute when building your project.

    使用此配置包括您希望Gradle在构建项目时执行的lint检查。

    Note: When using Android Gradle plugin 3.4.0 and higher, this dependency configuration no longer packages the lint checks in your Android Library projects. To include lint check dependencies in your AAR libraries, use the lintPublish configuration described below.

    注意:使用Android Gradle插件3.4.0及更高版本时,此依赖关系配置不再在您的Android库项目中打包lint检查。 要在AAR库中包含lint检查依赖项,请使用下面描述的lintPublish配置。

    lintPublish

    Use this configuration in Android library projects to include lint checks you want Gradle to compile into a lint.jar file and package in your AAR.

    在Android库项目中使用此配置,以包含您希望Gradle在AAR中编译为lint.jar文件和包的lint检查。

    This causes projects that consume your AAR to also apply those lint checks. If you were previously using the lintChecks dependency configuration to include lint checks in the published AAR, you need to migrate those dependencies to instead use the lintPublish configuration.

    这会导致使用AAR的项目也应用这些lint检查。 如果您之前使用lintChecks依赖关系配置在已发布的AAR中包含lint检查,则需要迁移这些依赖关系,而不是使用lintPublish配置。

    dependencies {
      // Executes lint checks from the ':checks' project at build time.
      lintChecks project(':checks')
      // Compiles lint checks from the ':checks-to-publish' into a lint.jar file and publishes it to your Android library.
      lintPublish project(':checks-to-publish')
    }

    依赖配置

    Dependency configurations

    为特定构建变体源集声明依赖项:configurations

    The above configurations apply dependencies to all build variants. If you instead want to declare a dependency for only a specific build variant source set or for a testing source set, you must capitalize the configuration name and prefix it with the name of the build variant or testing source set.

    以上配置适用于所有构建变体。如果您只想为特定的构建变体源集或测试源集声明依赖项,则必须将配置名称大写,并在其前面加上构建变量或测试源集的名称。

    For example, to add an implementation dependency only to your "free" product flavor, it looks like this:

    例如,要仅将 implementation 依赖项添加到 "free" 产品风味,它看起来像这样:

    freeImplementation 'com.google.firebase:firebase-ads:9.8.0' // Implementation 的基础上加 build variant 的前缀

    However, if you want to add a dependency for a variant that combines a product flavor and a build type, then you must initialize theconfiguration name in the configurations block. The following sample adds a runtimeOnly dependency to your "freeDebug" build variant:

    但是,如果要为组合 product flavor 和 build type 的变体添加依赖项,则必须在 configurations 块中初始化配置名称。 以下示例将 runtimeOnly 依赖项添加到"freeDebug"构建变体:

    configurations {
        //Initializes a placeholder for the freeDebugRuntimeOnly dependency configuration.
        freeDebugRuntimeOnly {} //初始化名称。free:product flavor; Debug:build type
    }
    dependencies {
        freeDebugRuntimeOnly fileTree(dir: 'libs', include: ['*.jar']) //使用
    }

    To add implementation dependencies for your local tests and instrumented tests , it looks like this:

    要为本地测试和instrumented测试添加 implementation 依赖项,它看起来像这样:

    testImplementation 'junit:junit:4.12' // Adds a remote binary dependency only for local tests.
    androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2' // only for the instrumented test APK.

    However, certain configurations don't make sense in this situation. For example, because other modules can't depend on androidTest, you get the following warning if you use the androidTestApi configuration:

    但是,某些配置在这种情况下没有意义。 例如,因为其他模块不能依赖于androidTest,所以如果使用androidTestApi配置,则会收到以下警告:
    WARNING: Configuration 'androidTestApi' is obsolete废弃 and has been replaced with 'androidTestImplementation'

    添加注释处理器:annotationProcessor

    Add annotation processors

    如果将注释处理器添加到编译类路径中,您将看到类似于以下内容的错误消息:

    Error: Annotation processors must be explicitly declared[显式声明] now.

    要解决此错误,请使用 annotationProcessor 配置依赖关系,为项目添加注释处理器,如 dagger2 可以按如下方式配置:

    // Adds libraries defining annotations to only the compile classpath. 仅将定义注释的库添加到编译类路径
    compileOnly 'com.google.dagger:dagger:version-number'
    // Adds the annotation processor dependency to the annotation processor classpath. 将注释处理器依赖项添加到注释处理器类路径
    annotationProcessor 'com.google.dagger:dagger-compiler:version-number'

    Note: Android Plugin for Gradle 3.0.0+ no longer supports android-apt plugin.

    将参数传递给注释处理器:argument

    Pass arguments to annotation processors

    If you need to pass arguments to an annotation processor, you can do so using the annotationProcessorOptions block in your module's build configuration. For example, if you want to pass primitive data types as key-value pairs, you can use the argument property, as shown below:

    如果需要将参数传递给注释处理器,则可以使用模块的构建配置中的 annotationProcessorOptions 块来执行此操作。例如,如果要将原始数据类型作为键值对传递,则可以使用argument属性,如下所示:

    android {
        defaultConfig {
            javaCompileOptions {
                annotationProcessorOptions {
                    argument "key1", "value1"
                    argument "key2", "value2"
                }
            }
        }
    }

    However, when using Android Gradle plugin 3.2.0 and higher, you need to pass processor arguments that represent files or directories using Gradle's CommandLineArgumentProvider interface.

    但是,使用Android Gradle插件3.2.0及更高版本时,需要使用Gradle的 CommandLineArgumentProvider 接口传递表示文件或目录的处理器参数。

    Using CommandLineArgumentProvider allows you or the annotation processor author to improve the correctness and performance of incremental and cached clean builds by applying incremental build property type annotations to each argument.

    使用 CommandLineArgumentProvider 允许您或注释处理器作者,通过将增量构建属性类型注释应用于每个参数,来提高增量和缓存干净构建的正确性和性能。

    For example, the class below implements CommandLineArgumentProvider and annotates each argument for the processor. The sample also uses the Groovy language syntax and is included directly in the module's build.gradle file.

    例如,下面的类实现了 CommandLineArgumentProvider 并为处理器注释了每个参数。该示例还使用Groovy语言语法,并直接包含在模块的 build.gradle 文件中。

    Note: Typically, annotation processor authors provide either this class or instructions on how to write such a class. That's because each argument needs to specify the correct build property type annotation in order to work as intended.

    注意:通常,注释处理器作者提供此类或有关如何编写此类的说明。 这是因为每个参数都需要指定正确的构建属性类型注释才能按预期工作。

    CommandLineArgumentProvider 示例

    class MyArgsProvider implements CommandLineArgumentProvider {
    
        // Annotates each directory as either an input or output for the annotation processor.
        @InputFiles
        // Using this annotation helps Gradle determine which part of the file path should be considered during up-to-date checks.
        @PathSensitive(PathSensitivity.RELATIVE)
        FileCollection inputDir
    
        @OutputDirectory
        File outputDir
    
        // The class constructor sets the paths for the input and output directories.
        MyArgsProvider(FileCollection input, File output) {
            inputDir = input
            outputDir = output
        }
    
        // Specifies each directory as a command line argument for the processor.
        // The Android plugin uses this method to pass the arguments to the annotation processor.
        @Override
        Iterable<String> asArguments() {
            // Use the form '-Akey[=value]' to pass your options to the Java compiler.
            ["-AinputDir=${inputDir.singleFile.absolutePath}", "-AoutputDir=${outputDir.absolutePath}"]
        }
    }
    
    android {...}

    After you create a class that implements CommandLineArgumentProvider, you need to initialize and pass it to the Android plugin using the annotationProcessorOptions.compilerArgumentProvider property, as shown below.

    在创建实现 CommandLineArgumentProvider 的类之后,需要使用 annotationProcessorOptions.compilerArgumentProvider 属性初始化并将其传递给 Android 插件,如下所示。

    // This is in your module's build.gradle file.
    android {
        defaultConfig {
            javaCompileOptions {
                annotationProcessorOptions {
                    // Creates a new MyArgsProvider object, specifies the input and
                    // output paths for the constructor, and passes the object to the Android plugin.
                    compilerArgumentProvider new MyArgsProvider(files("input/path"), new File("output/path"))
                }
            }
        }
    }

    To learn more about how implementing CommandLineArgumentProvider helps improve build performance, read Caching Java projects

    禁用注释处理器错误检查:includeCompileClasspath

    Disable the annotation processor error check

    If you have dependencies on the compile classpath that include annotation processors you don't need, you can disable the error check by adding the following to your build.gradle file. Keep in mind, the annotation processors you add to the compile classpath are still not added to the processor classpath.

    如果您对包含您不需要的注释处理器的 compile classpath 具有依赖性,则可以通过将以下内容添加到build.gradle文件来禁用错误检查。 请记住,添加到 compile classpath 的注释处理器仍未添加到 processor classpath 中。

    android {
        defaultConfig {
            javaCompileOptions {
                annotationProcessorOptions {
                    includeCompileClasspath false
                }
            }
        }
    }

    If you experience issues after migrating your project's annotation processors to the processor classpath, you can allow annotation processors on the compile classpath by setting includeCompileClasspath to true. However, setting this property to true is not recommended, and the option to do so will be removed in a future update of the Android plugin.

    如果在将项目的注释处理器迁移到 processor classpath 后遇到问题,则可以通过将 includeCompileClasspath 设置为 true 来允许编译类路径上的注释处理器。 但是,建议不要将此属性设置为 true,并且在将来的 Android 插件更新中将删除执行此操作的选项。

    排除传递依赖项:exclude

    Exclude transitive dependencies

    随着应用程序的增长,它可能包含许多依赖项,包括直接依赖项和传递依赖项(应用程序导入的库所依赖的库)。 要排除不再需要的传递依赖项,可以使用 exclude 关键字,如下所示:

    implementation('some-library') {
        exclude group: 'com.example.imgtools', module: 'native'
    }

    如果您需要从 tests 中排除某些传递依赖项,则上面显示的代码示例可能无法按预期工作。这是因为 test configuration 扩展了模块的 implementation 配置。 也就是说,当Gradle解析配置时,它始终包含 implementation 依赖性。

    因此,要从 tests 中排除传递依赖性,必须在 execution 时执行此操作,如下所示:

    android.testVariants.all { variant ->
        variant.getCompileConfiguration().exclude group: 'com.jakewharton.threetenabp', module: 'threetenabp'
        variant.getRuntimeConfiguration().exclude group: 'com.jakewharton.threetenabp', module: 'threetenabp'
    }

    Note: You can still use the exclude keyword in the dependencies block as shown in the original code sample from the Exclude dependencies section to omit transitive dependencies that are specific to the test configuration and are not included in other configurations.

    注意:您仍然可以在依赖项块中使用exclude关键字,如“排除依赖项”部分中的原始代码示例所示,以省略特定于测试配置但未包含在其他配置中的传递依赖项。

    使用变体感知依赖关系管理

    Use variant-aware dependency management

    Android plugin 3.0.0 and higher include a new dependency mechanism that automatically matches variants when consuming a library. This means an app's debug variant automatically consumes a library's debug variant, and so on. It also works when using flavors — an app's freeDebug variant will consume a library's freeDebug variant.

    Android插件3.0.0及更高版本包含一个新的依赖机制,可以在使用库时自动匹配变体。这意味着应用程序的debug变体会自动使用库的debug变体,依此类推。它在使用flavor时也有效 - 应用程序的freeDebug变体将使用库的freeDebug变体。

    In order for the plugin to accurately match variants, you need to provide matching fallbacks for instances where a direct match is not possible. Consider if your app configures a build type called "staging", but one of its library dependencies does not. When the plugin tries to build the "staging" version of your app, it won't know which version of the library to use, and you'll see an error message similar to the following:

    为了使插件准确匹配变体,您需要为无法直接匹配的实例提供 matching fallbacks。假如你的应用//程序配置了一个名为“staging”的构建类型,但其中一个库依赖项却没有。当插件尝试构建应用程序的“staging”版本时,它将不知道要使用的库版本,您将看到类似于以下内容的错误消息:

    Error:Failed to resolve: Could not resolve project :mylibrary.
    Required by:
        project :app

    The plugin includes DSL elements to help you control how Gradle should resolve situations in which a direct variant match between an app and a dependency is not possible. Consult the table below to determine which DSL property you should use to resolve certain build errors related to variant-aware dependency matching.

    该插件包含DSL元素,可帮助您控制Gradle应如何解决,无法在应用程序和依赖项之间进行直接变体匹配的情况。请参阅下表以确定应使用哪个DSL属性来解决与变体感知依赖项匹配相关的某些构建错误。

    app 包含依赖库不包含的 buildTypes:matchingFallbacks

    Your app includes a build type that a library dependency does not.

    Specifies a sorted list of fallback build types that the plugin should try to use when a dependency does not include a "staging" build type. You may specify as many fallbacks as you like, and the plugin selects the first build type that's available in the dependency.

    指定插件在依赖项不包含 staging 构建类型时,应尝试使用的回退构建类型的排序列表。您可以根据需要指定尽可能多的回退,并且插件会选择依赖项中可用的第一个构建类型。

    For example, your app includes a "staging" build type, but a dependency includes only a "debug" and "release" build type.

    例如,您的应用程序包含“staging”构建类型,但依赖项仅包括“debug”和“release”构建类型。

    Use matchingFallbacks to specify alternative matches for a given build type, as shown below:

    使用 matchingFallbacks 为给定的构建类型指定替代匹配,如下所示:

    // In the app's build.gradle file.
    android {
        buildTypes {
            debug {...}
            release {...}//由于依赖项已包含此构建类型,因此您无需在此处提供 matchingFallbacks
            stage {
                matchingFallbacks = ['debug', 'qa'] //指定当依赖项不包含此构建类型时,应尝试使用的构建类型的排序列表
            }
        }
    }

    Note that there is no issue when a library dependency includes a build type that your app does not. That's because the plugin simply never requests that build type from the dependency.

    请注意,当库依赖项包含您的应用程序不包含的构建类型时,没有问题。 那是因为插件根本不会从依赖项中请求构建类型。

    app 包含依赖库不包含的 productFlavors:matchingFallbacks

    For a given flavor dimension that exists in both the app and its library dependency, your app includes flavors that the library does not.

    For example, both your app and its library dependencies include a "tier" flavor dimension. However, the "tier" dimension in the app includes "free" and "paid" flavors, but a dependency includes only "demo" and "paid" flavors for the same dimension.

    例如,您的 app 及其库依赖项都包含“tier”风格维度。但是,应用程序中的“tier”维度包括 "free" and "paid" 风格,但依赖项仅包括相同维度的 "demo" and "paid” 风格。

    Use matchingFallbacks to specify alternative matches for theapp's "free" product flavor, as shown below:

    使用matchingFallbacks为应用程序的“free”产品风格指定替代匹配,如下所示:

    Do not configure matchingFallbacks in the defaultConfig block. Instead, you must specify fallbacks for a given product flavor in the productFlavors block, as shown below.

    不要在defaultConfig块中配置matchingFallbacks。相反,您必须在productFlavors块中指定给定 roduct Flavors 的回退,如下所示。

    Specifies a sorted list of fallback flavors that the plugin should try to use when a dependency's matching dimension does not include a "free" flavor. You may specify as many fallbacks as you like, and the plugin selects the first flavor that's available in the dependency's "tier" dimension.

    指定当依赖项的匹配 dimension 不包含“free”风格时,插件应尝试使用的后备风格的排序列表。您可以根据需要指定尽可能多的回退,并且插件会选择依赖项的“tier”维度中可用的第一个flavor。

    // In the app's build.gradle file.
    android {
        defaultConfig{...} //不要在defaultConfig块中配置matchingFallbacks,而要在具体的productFlavors中配置
        flavorDimensions 'tier' //风格维度
        productFlavors { //产品风格
            paid {
                dimension 'tier' //由于依赖库中风格维度tier下也有此productFlavors,因此无需提供matchingFallbacks
            }
            free {
                dimension 'tier' //由于依赖库中风格维度tier下没有此productFlavors,因此需要提供matchingFallbacks
                matchingFallbacks = ['demo', 'trial'] //排序列表中指定的是【库】中可能有的productFlavors
            }
        }
    }

    Note that, for a given flavor dimension that exists in both the app and its library dependencies, there is no issue when a library includes a product flavor that your app does not. That's because the plugin simply never requests that flavor from the dependency.

    请注意,对于应用程序及其库依赖项中存在的给定风味维度,当库包含app不包含的 product flavor 时,不会出现问题。 那是因为插件根本不会从依赖中请求那种flavors。

    依赖库包括 app 不具有的 flavorDimensions:missingDimensionStrategy

    A library dependency includes a flavor dimension that your app does not.

    For example, a library dependency includes flavors for a "minApi" dimension, but your app includes flavors for only the "tier" dimension. So, when you want to build the "freeDebug" version of your app, the plugin doesn't know whether to use the "minApi23Debug" or "minApi18Debug" version of the dependency.

    例如,库依赖项包括“minApi”维度的风格,但您的app仅包含“tier”维度的风格。因此,当您想要构建app的“freeDebug”版本时,该插件不知道是否使用依赖项的“minApi23Debug”或“minApi18Debug”版本。

    Use missingDimensionStrategy in the defaultConfig block to specify the default flavor the plugin should select from each missing dimension, as shown in the sample below. You can also override your selections in the productFlavors block, so each flavor can specify a different matching strategy for a missing dimension.

    在defaultConfig块中使用missingDimensionStrategy指定插件应从每个缺少的维度中选择的默认flavor,如下面的示例所示。 您还可以覆盖productFlavors块中的选择,因此每种flavor都可以为缺少的维度指定不同的匹配策略。

    Specifies a sorted list of flavors that the plugin should try to use from a given dimension. The following tells the plugin that, when encountering a dependency that includes a "minApi" dimension, it should select the "minApi18" flavor. You can include additional flavor names to provide a sorted list of fallbacks for the dimension.

    指定插件应尝试从给定维度使用的排序样式列表。 以下告诉插件,当遇到包含“minApi”维度的依赖项时,它应该选择“minApi18”风格。您可以包含其他flavor名称,以提供维度的回退的排序列表。

    You should specify a missingDimensionStrategy property for each dimension that exists in a local dependency but not in your app.

    您应该为本地依赖项中存在但不在应用程序中的每个维度指定missingDimensionStrategy属性。

    You can override the default selection at the product flavor level by configuring another missingDimensionStrategy property for the "minApi" dimension.

    您可以通过为“minApi”维度配置另一个missingDimensionStrategy属性来覆盖产品风格级别的默认选择。

    // In the app's build.gradle file.
    android {
        defaultConfig{
            missingDimensionStrategy 'minApi', 'minApi18', 'minApi23' //优先使用依赖库 minApi 下的 minApi18
            missingDimensionStrategy 'abi', 'x86', 'arm64' //优先使用依赖库 abi 下的 x86
        }
        flavorDimensions 'tier'
        productFlavors {
            free {
                dimension 'tier'
                missingDimensionStrategy 'minApi', 'minApi23', 'minApi18' //覆盖默认配置
            }
            paid {...}
        }
    }

    Note that there is no issue when your app includes a flavor dimension that a library dependency does not. That's because the plugin matches flavors of only the dimensions that exist in the dependency. For example, if a dependency did not include a dimension for ABIs, the "freeX86Debug" version of your app would simply use the "freeDebug" version of the dependency.

    请注意,当您的app包含库依赖项不包含的flavor dimension时,不会出现问题。那是因为插件只匹配依赖项中存在的维度。 例如,如果依赖项不包含ABI的维度,则app的“freeX86Debug”版本将仅使用依赖项的“freeDebug”版本。

    远程存储库

    Remote repositories

    When your dependency is something other than a local library or file tree, Gradle looks for the files in whichever online repositories are specified in the repositories block of your build.gradle file.

    当您的依赖项不是本地库或文件树时,Gradle将在build.gradle文件的repositories块中指定的任何联机存储库中查找文件。

    The order in which you list each repository determines the order in which Gradle searches the repositories for each project dependency. For example, if a dependency is available from both repository A and B, and you list A first, Gradle downloads the dependency from repository A.

    列出每个存储库的顺序决定了Gradle在每个项目依赖项中搜索存储库的顺序。例如,如果存储库A和B都需要使用一个依赖项,并且您首先列出A,则Gradle将从存储库A下载依赖项。

    By default, new Android Studio projects specifies Google's Maven repository and JCenter as repository locations in the project's top-level build.gradle file, as shown below:

    默认情况下,新建的Android Studio项目将Google的Maven存储库和JCenter指定为项目顶级build.gradle文件中的存储库位置,如下所示:

    allprojects {
        repositories {
            google()
            jcenter()
        }
    }

    If you want something from the Maven central repository, then add mavenCentral(), or for a local repository use mavenLocal():

    如果你想要 Maven central 存储库中的东西,那么添加 mavenCentral(),或者对于本地存储库使用mavenLocal():

    allprojects {
        repositories {
            google()
            jcenter()
            mavenCentral() //maven中央存储库
            mavenLocal()  //maven本地存储库
        }
    }

    Or you can declare specific Maven or Ivy repositories as follows:

    或者,您可以按如下方式声明特定的Maven或Ivy存储库:

    allprojects {
        repositories {
            maven { url "https://repo.example.com/maven2" }
            maven { url "file://local/repo/" }
            ivy { url "https://repo.example.com/ivy" }
        }
    }

    For more information, see the Gradle Repositories guide.

    谷歌的Maven存储库

    Google's Maven repository

    The most recent versions of the following Android libraries are available from Google's Maven repository:

    You can see all available artifacts at Google's Maven repository index (see below for programmatic access).

    添加Google的Maven中提供的library

    To add one of these libraries to your build, include Google's Maven repository in your top-level build.gradle file:

    要在构建中添加其中一个库,请在顶级build.gradle文件中包含Google的Maven存储库:

    allprojects {
        repositories {
            google() //如果您使用的Gradle版本低于4.1,则必须使用【maven { url 'https://maven.google.com'}】
        }
    }

    然后将所需的库添加到模块的 dependencies 块中。 例如,appcompat库如下所示:

    implementation 'com.android.support:appcompat-v7:27.1.1'

    However, if you're trying to use an older version of the above libraries and your dependency fails, then it's not available in the Maven repository and you must instead get the library from the offline repository.

    但是,如果您尝试使用上述库的旧版本,并且您的依赖项失败,那么它在Maven存储库中不可用,您必须从offline存储库获取库。

    程序化访问

    [Programmatic access]

    要以编程方式访问Google的Maven工件,您可以从 maven.google.com/master-index.xml 获取工件组的XML列表。然后,对于任何 group,您可以在以下位置查看其 library 的名称和版本:

    maven.google.com/group_path/group-index.xml

    例如,android.arch.lifecycle组中的库列在maven.google.com/android/arch/lifecycle/group-index.xml

    您还可以在以下位置下载POM和JAR文件:

    maven.google.com/group_path/library/version /library-version.ext

    例如:maven.google.com/android/arch/lifecycle/compiler/1.0.0/compiler-1.0.0.pom

    SDK Manager 中的离线存储库

    Offline repository from SDK Manager

    For libraries not available from the Google Maven repository (usually older library versions), you must download the offline Google Repository package from the SDK Manager. Then you can add these libraries to your dependencies block as usual.

    对于Google Maven存储库不可用的库(通常是较旧的库版本),您必须从SDK Manager下载脱机Google Repository包。然后,您可以像平常使用的方式一样将这些库添加到依赖项块中。

    脱机库保存在 android_sdk/extras/ 中。

    依赖关系

    依赖顺序

    Dependency order

    The order in which you list your dependencies indicates the priority for each: the first library is higher priority than the second, the second is higher priority than the third, and so on. This order is important in the event that resources are merged or manifest elements are merged into your app from the libraries.

    列出依赖项的顺序表示每个依赖项的优先级:第一个库的优先级高于第二个库,第二个库的优先级高于第三个库,依此类推。 在合并资源或将清单元素从库合并到您的应用程序中时,此顺序非常重要。

    例如,如果您的项目声明以下内容:

    • 按顺序依赖 LIB_A 和 LIB_B
    • 并且 LIB_A 按顺序依赖于 LIB_C 和 LIB_D
    • LIB_B 也依赖于 LIB_C

    然后,flat 依赖顺序如下:LIB_A LIB_D LIB_B LIB_C
    这可以确保 LIB_A 和 LIB_B 都可以覆盖 LIB_C;LIB_D的优先级仍然高于 LIB_B,因为 LIB_A 的优先级高于 LIB_B。

    其实这个顺序并不是特别好理解

    For more information about how manifests from different project sources/dependencies are merged, see Merge multiple manifest files.

    查看依赖关系树

    [View the dependency tree]

    Some direct dependencies may have dependencies of their own. These are called transitive dependencies. Rather than requiring you to manually declare each transitive dependency, Gradle automatically gathers and adds them for you.

    某些直接依赖关系可能具有自己的依赖关系。 这些被称为传递依赖。Gradle不会要求您手动声明每个传递依赖项,而是自动收集并添加它们。

    To visualize both the direct and transitive dependencies of your project, the Android plugin for Gradle provides a Gradle task that generates a dependency tree for each build variant and testing source set.

    为了可视化项目的直接依赖性和传递性依赖性,Gradle的Android插件提供了一个Gradle任务,该任务为每个构建变体和测试源集生成依赖关系树。

    要运行任务,请执行以下操作:

    • 选择 View > Tool Windows > Gradle(或直接单击工具窗口栏中的“Gradle”窗体)。
    • 展开 AppName > Tasks > android > androidDependencies。双击执行Gradle任务后,应该会打开 Run 窗口以显示输出。

    The following sample output shows the dependency tree for the debug build variant, and includes the local library module dependency and remote dependency from the previous example.

    以下示例输出显示了调试版本构建变体的依赖关系树,并包含上一示例中的本地库模块依赖关系和远程依赖关系。

    Executing tasks: [androidDependencies]
    :app:androidDependencies
    debug
    +--- MyApp:mylibrary:unspecified
    |    \--- com.android.support:appcompat-v7:27.1.1
    |         +--- com.android.support:animated-vector-drawable:27.1.1
    |         |    \--- com.android.support:support-vector-drawable:27.1.1
    |         |         \--- com.android.support:support-v4:27.1.1
    |         |              \--- LOCAL: internal_impl-27.1.1.jar
    |         +--- com.android.support:support-v4:27.1.1
    |         |    \--- LOCAL: internal_impl-27.1.1.jar
    |         \--- com.android.support:support-vector-drawable:27.1.1
    |              \--- com.android.support:support-v4:27.1.1
    |                   \--- LOCAL: internal_impl-27.1.1.jar
    \--- com.android.support:appcompat-v7:27.1.1
         +--- com.android.support:animated-vector-drawable:27.1.1
         |    \--- com.android.support:support-vector-drawable:27.1.1
         |         \--- com.android.support:support-v4:27.1.1
         |              \--- LOCAL: internal_impl-27.1.1.jar
         +--- com.android.support:support-v4:27.1.1
         |    \--- LOCAL: internal_impl-27.1.1.jar
         \--- com.android.support:support-vector-drawable:27.1.1
              \--- com.android.support:support-v4:27.1.1
                   \--- LOCAL: internal_impl-27.1.1.jar
    ...

    For more information about managing dependencies in Gradle, see Dependency management basics in the Gradle User Guide.

    解决重复的类错误

    [Resolve duplicate class errors]

    When you add multiple dependencies to your app project, those direct and transitive dependencies might conflict with one another. The Android Gradle Plugin tries to resolve these conflicts gracefully, but some conflicts may lead to compile time or runtime errors.

    当您向应用程序项目添加多个依赖项时,这些直接和传递依赖项可能会相互冲突,Android Gradle Plugin尝试优雅地解决这些冲突,但是一些冲突可能导致编译时或运行时错误。

    To help you investigate which dependencies are contributing to errors, inspect your app's dependency tree and look for dependencies that appear more than once or with conflicting versions.

    为了帮助您调查哪些依赖项导致错误,请检查应用程序的依赖关系树,并查找出现多次或存在冲突版本的依赖项。

    If you can't easily identify the duplicate dependency, try using Android Studio's UI to search for dependencies that include the duplicate class as follows:

    如果您无法轻松识别重复的依赖项,请尝试使用Android Studio的UI搜索包含重复类的依赖项,如下所示:

    • Select Navigate > Class from the menu bar.
    • In the pop-up search dialog, make sure that the box next to Include non-project items is checked.
    • Type键入 the name of the class that appears in the build error.
    • Inspect检查 the results for the dependencies that include the class.

    The following sections describe the different types of dependency resolution errors you may encounter and how to fix them.

    以下部分描述了您可能遇到的不同类型的依赖项解析错误,以及如何解决这些错误。

    修复重复class错误

    Fix duplicate class errors

    例如,如果一个类在 runtime classpath 上出现多次,则会出现类似以下的错误:

    Program type already present com.example.MyClass

    此错误通常会在下列情况之一时发生:

    • A binary dependency includes a library that your app also includes as a direct dependency.

    For example, your app declares a direct dependency on Library A and Library B, but Library A already includes Library B in its binary.
    To resolve this issue, remove Library B as a direct dependency.

    • Your app has a local binary dependency and a remote binary dependency on the same library.

    To resolve this issue, remove one of the binary dependencies.

    修复classpaths之间的冲突

    Fix conflicts between classpaths

    When Gradle resolves the compile classpath, it first resolves the runtime classpath and uses the result to determine确定 what versions of dependencies should be added to the compile classpath. In other words, the runtime classpath determines确定 the required version numbers for identical相同 dependencies on downstream下游 classpaths.

    当Gradle解析编译类路径时,它首先解析运行时类路径,并使用此结果来确定应将哪些版本的依赖项添加到编译类路径中。换句话说,运行时类路径确定下游类路径上相同依赖项所需的版本号。

    Your app's runtime classpath also determines the version numbers that Gradle requires for matching dependencies in the runtime classpath for the app's test APK. The hierarchy of classpaths is described in figure 1.

    您的应用程序的运行时类路径还确定了Gradle在应用程序测试APK的运行时类路径中匹配依赖项所需的版本号。类路径的层次结构如图1所示。

    Figure 1. Version numbers of dependencies that appear across multiple classpaths must match according to this hierarchy. 多个类路径中出现的依赖关系的版本号必须根据此层次结构匹配。

    A conflict where different versions of the same dependency appears across multiple classpaths migh occur when, for example, your app includes a version of a dependency using the implementation dependency configuration and a library module includes a different version of the dependency using the runtimeOnly configuration.

    例如,当您的app包含使用implementation依赖项配置的依赖项版本,并且库模块包含使用runtimeOnly配置的不同版本的依赖项时,会出现多个类路径中出现相同依赖关系的不同版本的冲突。

    When resolving dependencies on your runtime and compile time classpaths, Android Gradle plugin 3.3.0 and higher attempt to automatically fix certain downstream version conflicts. For example, if the runtime classpath includes Library A version 2.0 and the compile classpath includes Library A version 1.0, the plugin automatically updates the dependency on the compile classpath to Library A version 2.0 to avoid errors.

    在解析运行时和编译时类路径的依赖关系时,Android Gradle插件3.3.0及更高版本会尝试自动修复某些下游版本冲突。例如,如果运行时类路径包含库A版本2.0并且编译类路径包含库A版本1.0,则插件会自动将编译类路径的依赖性更新为库A版本2.0以避免错误。

    However, if the runtime classpath includes Library A version 1.0 and the compile classpath includes Library A version 2.0, the plugin does not downgrade the dependency on the compile classpath to Library A version 1.0, and you still get an error similar to the following:

    但是,如果运行时类路径包含库A版本1.0且编译类路径包含库A版本2.0,则插件不会将编译类路径上的依赖项降级为库A版本1.0,并且仍会出现类似于以下内容的错误:

    Conflict with dependency 'com.example.library:some-lib:2.0' in project 'my-library'.
    Resolved versions for runtime classpath (1.0) and compile classpath (2.0) differ.

    要解决此问题,请执行以下操作之一:

    • Include the desired version of the dependency as an api dependency to your library module. That is, only your library module declares the dependency, but the app module will also have access to its API, transitively.

      将所需的依赖项版本作为 api 依赖项包含在库模块中。也就是说,只有你的库模块声明了依赖关系,但 app 模块也可以传递访问它的API。

    • Alternatively, you can declare the dependency in both modules, but you should make sure that each module uses the same version of the dependency. Consider configuring project-wide properties to ensure versions of each dependency remain consistent保持一致 throughout your project.

      或者,您可以在两个模块中声明依赖项,但应确保每个模块使用相同版本的依赖项。 考虑配置项目范围的属性,以确保每个依赖项的版本在整个项目中保持一致。

    应用自定义构建逻辑

    [Apply custom build logic]

    以下内容实际工作中还没有使用过

    This section describes advanced topics that are useful when you want to extend the Android Gradle plugin or write your own plugin.

    本节介绍了在扩展 Android Gradle 插件或编写自己的插件时非常有用的高级主题。

    将变体依赖项发布到自定义逻辑

    Publish variant dependencies to custom logic

    A library can have functionalities that other projects or sub-projects might want to use. Publishing a library is the process by which the library is made available to its consumers. Libraries can control which dependencies its consumers have access to at compile time and runtime.

    库中可以具有其他项目或子项目可能想要使用的功能。发布库是向其使用者提供库的过程。库可以控制其消费者在编译时和运行时可以访问的依赖项。

    There are two separate configurations that hold the transitive dependencies of each classpath which must be used by consumers to consume the library as described below:

    有两个独立的配置,用以保存每个类路径的传递依赖关系,消费者必须使用它们来使用库,如下所述:

    • variant_nameApiElements: This configuration holds the transitive dependencies that are available to consumers at compile time.
    • variant_nameRuntimeElements: This configuration holds the transitive dependencies that are available to consumers at runtime.

    To learn more about the relationships between the different configurations, go to The Java Library plugin configurations

    自定义依赖解析策略

    [Custom dependency resolution strategies]

    A project may include a dependency on two different versions of the same library which can lead to dependency conflicts. For example, if your project depends on version 1 of module A and version 2 of module B, and module A transitively depends on version 3 of module B, there arises a dependency version conflict.

    项目可能包括对同一库的两个不同版本的依赖,这可能导致依赖性冲突。例如,如果您的项目依赖于模块A的版本1和模块B的版本2,并且模块A transitively 地依赖于模块B的版本3,则会出现依赖版本冲突。

    To resolve this conflict, the Android Gradle Plugin uses the following dependency resolution strategy: when the plugin detects that different versions of the same module are in the dependency graph, by default, it chooses the one with the highest version number.

    为解决此冲突,Android Gradle Plugin使用以下依赖项解析策略:当插件检测到同一模块的不同版本在依赖关系图中时,默认情况下,它会选择版本号最高的版本。

    However, this strategy might not always work as you intend. To customize the dependency resolution strategy, use the following configurations to resolve specific dependencies of a variant that are needed for your task:

    但是,此策略可能并不总是按您的意愿运行。要自定义依赖项解析策略,请使用以下配置来解析任务所需的变体的特定依赖项:

    • variant_nameCompileClasspath:This configuration contains the resolution strategy for a given variant’s compile classpath.
    • variant_nameRuntimeClasspath:This configuration contains the resolution strategy for a given variant’s runtime classpath.

    The Android Gradle plugin includes getters that you can use to access the configuration objects of each variant. Thus, you can use the variant API to query the dependency resolution as shown in the example below:

    Android Gradle插件包含可用于访问每个变体的配置对象的getter方法。 因此,您可以使用 variant API 来查询依赖项解析,如下例所示:

    精简版

    android {
        applicationVariants.all { variant ->
            variant.getCompileConfiguration().resolutionStrategy {...} //返回一个variant的compile configuration objects
            variant.getRuntimeConfiguration().resolutionStrategy  {...}
            variant.getAnnotationProcessorConfiguration().resolutionStrategy {...}
        }
    }

    完整版

    android {
        applicationVariants.all { variant ->
            variant.getCompileConfiguration().resolutionStrategy { //Return compile configuration objects of a variant.
            // Use Gradle's ResolutionStrategy API to customize自定义 how this variant resolves dependencies.
                ...
            }
            variant.getRuntimeConfiguration().resolutionStrategy {  //Return runtime configuration objects of a variant.
                ...
            }
            variant.getAnnotationProcessorConfiguration().resolutionStrategy { //Return annotation processor configuration of a variant.
                ...
            }
        }
    }

    最后更新日期:August 16, 2018.

    2019-5-12

    转载于:https://www.cnblogs.com/baiqiantao/p/10854312.html

    展开全文
  • Gradle 翻译 此项目为 Gradle 翻译项目,使用 OmegaT 辅助翻译软件,目前翻译版本为 Gradle 2.0。翻译的章节,将合并到 项目当中。 加入翻译 1.下载并安装OmegaT 你可以从OmegaT官网上下载,或者从我的百度网盘中...
  • Gradle官方文档中文翻译 gradle-user-guide
  • Gradle1.12的翻译情况Gradle实际上在4月16日就已经在对应的OmegaT项目上完成了翻译,后因项目繁忙,直到7月20日才完成了Github上Gradledoc项目及七牛站点的更新。 总结一下1.12的翻译情况: 从2014年11月12日开始...

    Gradle1.12的翻译情况

    Gradle实际上在4月16日就已经在对应的OmegaT项目上完成了翻译,后因项目繁忙,直到7月20日才完成了Github上Gradledoc项目及七牛站点的更新。
    总结一下1.12的翻译情况:

    • 从2014年11月12日开始使用OmagaT翻译,到2017年4月16日完成最后一章的翻译,一共用了两年半的时间,提交了1380次。
    • 翻译过程中使用OmegaT,并且是按句子分割进行翻译,读起来连贯性不足。
    • 本人英语很一般,翻译结果多为直译,比较生硬。

    Gradle2.0的翻译开始

    为什么不是翻译当前最新的版本?

    Gradle的更新太快了,以我目前翻译的龟速,永远翻译不了最新版本。所以我的想法是先翻译出一个完整的版本,然后按Gradle的版本的顺序,继续下一次完整版本的翻译。这样做有以下好处:

    • 使用了CAT软件,所以在翻译完一个版本之后,再翻译下一版本速度会有提升。
    • 原先翻译得不好的句子,在下一版本之后可能会获得改进。

    Gradle2.0的翻译会有哪些提升?

    • 首先从2.0开始,我改为以段落为单位进行分割翻译,所以至少每一段的句子之间连贯性会改善。
    • 其次,我这一年来也在开始努力地学英语啦(嗯……在背单词,从初中开始背起,还没背完),语感比两年前要好那么一丢丢。
    • 旧版本的翻译结果将作为新版本翻译的参考。
    • 这两年,机器翻译(谷歌翻译)已有很大进步(大实话)。
    • 我会尽量统一里面出现的软件开发术语的翻译。
    • 尽量使翻译结果更准确。

    如何参与翻译?

    可以在Gradledoc项目上提交PR(推荐),提交新章节的翻译结果或是对现有翻译进行校正。

    展开全文
  • 文本并不会对此进行长篇大论,你可以查看Gradle 特性列表 和 Gradle与Maven之间的性能比较 获取更多信息。 灵活性 谷歌(Google)选择将 Gradle 作为安卓的官方构建工具;并不是因为构建脚本是代码的缘故,...

     

    以下是对 Gradle 和 Apache Maven 之间主要不同点的总结,概括为:灵活性,性能,用户体验和依赖管理。文本并不会对此进行长篇大论,你可以查看Gradle 特性列表 和 Gradle与Maven之间的性能比较 获取更多信息。

    灵活性

    谷歌(Google)选择将 Gradle 作为安卓的官方构建工具;并不是因为构建脚本是代码的缘故,而是因为 Gradle  采用了一种最基本的可扩展方式进行建模。Gradle 的模型还允许它可以用 C/C++ 进行本地开发,叶可以扩展到覆盖任何生态系统。比如,Gradle 使用其 Tooling API 来实现一些嵌入功能。

    Gradle 和 Maven 都支持约定优于配置。不过,Maven 提供的模型非常僵化,以至于一些自定义操作冗长重复到令人讨厌,有时候甚至根本不可能完成。虽然这让我们更容易理解任何给定的 Maven 构建,只要你没有特殊需求,这也使得它不适合许多自动化问题。而 Gradle 则是由一个掌握由更多权限,负更多责任的用户来构建的。

    性能

    缩短构建时间是加速打包最直接的方式之一。Gradle 和 Maven 都是使用了某种并行项目构建和并行依赖解析。最大的区别在于 Gradle 的工作避免和增量构建机制。以下三个最重要的特征使得 Gradle 比 Maven 快得多:

    • 增量构建 — Gradle 通过跟踪任务的输入输出来避免不必要的工作,且只在需要的时候运行,当可能的时候只处理那些就改过了的文件。
    • 构建缓存 — 重用其他任意 Gradle 构建的结果,只要输入相同就可以重用,包括不同的机器之间。
    • 守护进程 — 一个长期驻留的后台守护进程,在内存中维护“热”的构建信息数据。

    在这个性能比较中,以上以及其他 提升性能的特性 使得 Gradle 几乎在每个场景都比 Maven 快至少一倍(在使用构建缓存进行大型构建时快100倍)。

    用户体验

    Maven 在历史上使用时间更长,这意味着对于许多用户,它的对IDE的支持更好。Gradle 对IDE的支持在持续不断快速进步。不过,目前 Gradle 提供了一个基于 Kotlin 的领域特征语言(DSL),对于IDE有更好的体验。Gradle 团队正在更IDE开发商合作来使得编辑支持更加好 — 尽请期待 更新。

    虽然IDE很重要,不过仍然有非常多的用户更愿意通过命令行界面执行构建操作。Grdle 提供了一个更加现代的CLI,具有像 “gradle task”这样的自动发现特性,也有改进之后的日志功能和命令行补全(command-line completion)功能。

    最后,Gradle 为调试和优化构建提供了一个基于web的可交互UI:构建扫描。在允许某个组织收集构建历史信息,做趋势分析,为调试比较构建的差异,以及优化构建时间的前提下,这些都可以被托管。

    依赖管理

    A Gradle build scan

    这两个构建系统都提供了内置的基于可配置的仓库的依赖解析能力。也都支持本地依赖缓存和依赖并行下载。

    Maven 允许仓库的消费者覆盖依赖,但只能通过写入不同的版本(version)来实现。Gradle 提供自定义的依赖选择候补规则,只需一次声明,就能在项目范围内处理所有不想要的依赖。这个候补规则使得Gradle可以通过多个源代码工程一起构建来创建复合构建

    Maven 的内置依赖作用域很少,而且对于一些常见的比如测试工具或者代码生成场景,强迫用户使用笨拙的模块结构。比如,它根本就不区分单元测试和集成测试。Gradle 允许自定义依赖作用域,提供更好的模型和更快的构建。

    Gradle 允许仓库的生产者声明依赖的API和实现来防止不想要的库泄露到消费者的类路径中。Maven 则允许发布者通过可选依赖提供元数据。

    展开全文
  • android_studio Gradle翻译

    2015-04-02 13:58:12
    详情查看地址:http://blog.csdn.net/column/details/gradle-translation.html
  • gradle翻译文档地址

    2015-11-26 23:34:42
    gradle 中文翻译文档: http://avatarqing.github.io/Gradle-Plugin-User-Guide-Chinese-Verision/introduction/README.html
  • 跟随本教程,您将创建出一个简单的Gradle项目、调用一些基础的Gradle命令,并对Gradle如何进行项目管理有初步的了解。 准备工作 大约12分钟的时间 控制台或IDE应用程序 Java开发套件(JDK),如果要使用Gradle ...
  • Gradle 定义了 6 个日志级别,如表18.1,“日志级别”所示。除了你可能通常都会看到的日志级别之外,还有两个 Gradle 特定的日志级别。这两个级别分别是QUIET和LIFECYCLE。默认使用后面的这个日志级别,用于报告...
  • Gradle 项目可以对其他组件具有依赖关系。这些组件可以是外部的二进制包,或其他的 Gradle 项目。 二进制包的依赖 本地包 要配置一个外部库 jar 包的依赖,您需要在compile配置中添加一个依赖关系。 dependencies...
  • 在做多语言项目的时候,当涉及地区相对较多的时候,翻译管理是个比较麻烦的事,下面的代码脚本自动将 md 格式的翻译文件转换成 Android 需要的 .xml 格式的文件. 翻译文件格式: 转换之后的格式: 具体代码如下:...
  • 13.1. Gradle 构建语言 Gradle 提供一种领域特定语言或者说是 DSL,来描述构建。这种构建语言基于 Groovy 中,并进行了一些补充,使其易于描述构建。 13.2. Project API 在第 7 章, Java 快速入门的教程中,我们...
  • 本章介绍了Gradle命令行的基础知识,正如你在前面章节所看到的使用gradle命令来运行构建。 11.1. 执行多个任务 你可以通过在命令行中列出每个任务来在单个构建中执行多个任务。例如,gradle compile test命令将执行...
  • 翻译项目请关注Github上的地址:https://github.com/msdx/gradledoc。 本文翻译所在分支:https://github.com/msdx/gradledoc/tree/2.0。更好的阅读体验请访问:...
  • 这是gradle 2.14版本的官方用户指南对应的中文翻译文档,里面有对gradle全面而详细的介绍。想看对应的英文版的请访问:https://docs.gradle.org/2.14/userguide/userguide.html(国内访问速度很慢,需要自备梯子)。
  • Gradle 包装器(下称“包装器”)是启动 Gradle 构建的首选方法。这个包装器是Windows上的一个批处理脚本和以及用于其他操作系统的shell 脚本。当你通过包装器启动 Gradle 构建时,Gradle 将被自动下载并用于运行这...
  • 翻译项目请关注Github上的地址:https://github.com/msdx/gradledoc 。 本文翻译所在分支:https://github.com/msdx/gradledoc/tree/2.0 。更好的阅读体验请访问:...
  • Gradle 守护进程(有时也称为构建守护进程) 旨在改善 Gradle 的启动和执行时间。 我们想到了几个关于守护进程非常有用的情形。对于一些工作流,用户会多次调用 Gradle 以执行少量相对较快的任务。例如: 当使用...
  • 翻译项目请关注Github上的地址:https://github.com/msdx/gradledoc。 本文翻译所在分支:https://github.com/msdx/gradledoc/tree/2.0。更好的阅读体验请访问:...
  • 安装Gradle Chapter 4. Installing Gradle 4.1. 环境要求 4.1. Prerequisites Gradle需要安装Java6或更高以上版本的JDK或JRE。Gradle自带了Groovy库,因此不需要安装Groovy。已经安装的Groovy会被Gradle所忽略。 ...
  • 进入新的页面之后,找到并点击下载完整版本(英文看不懂可以先将网站翻译成中文) 下载完成之后,解压后放入自己想要放入的指定文件夹,我放入了C:\WorkSoftware\gradle-4.5 step3: 配置环境变量 从控制面板进入...
  • gradle基础使用教程

    2016-04-28 11:44:27
    翻译gradle官网的针对APP DEVELOPER的教程,希望对你能有帮助。
  • Gradle 添加了一些概念和 API 来帮助您实现这一目标。 16.1. 定位文件 你可以使用Project.file()方法来找到一个相对于项目目录的文件 。 您可以把任何对象传递给file()方法,而它将尝试将其转换为一个绝对路径的...
  • build.gradle apply plugin: 'maven' 52.2. 任务 Maven 插件定义了以下任务: 表 52.1. Maven 插件 - 任务 任务名称 依赖于 类型 描述 install 所有构建相关archives的任务。 Upload 将相关的
  • Gradle 提供了对 Ant 的优秀集成您可以在你的 Gradle 构建中,使用单独的 Ant 任务或整个 Ant 构建。事实上,你会发现在 Gradle 中使用 Ant 任务比使用 Ant 的XML 格式更容易也更强大。你甚至可以只把 Gradle 当作一...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 11,634
精华内容 4,653
关键字:

gradle翻译