Gradle 翻译 build dependencies 依赖 [MD]

摘要:
本页介绍如何在Android项目中使用依赖项。它只包含有关Android特定Gradle插件的行为和配置的详细信息[指定给Gradle的Android插件]。依赖项类型要向项目添加依赖项,请单击“构建”。依赖项配置在gradle文件的依赖项块中指定。本地库模块依赖:projectLocal库模块依赖这声明了对名为“mylibrary”的Android库模块的依赖。换句话说,使用实现指令的依赖关系仅适用于当前模块,不会被传递。implementationimplementation可以看作是一个紧凑的compileGradle,它将依赖项添加到编译类路径中,并将依赖项打包到构建输出中。

博文地址

我的GitHub我的博客我的微信我的邮箱
baiqiantaobaiqiantaobqt20094baiqiantao@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,而不会传递

例如,有一个 moduletestsdk依赖于 gson:implementation 'com.google.code.gson:gson:2.8.2'
另一个 moduleapp依赖于 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 toexecutewhen building your project.

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

Note: When usingAndroid Gradle plugin 3.4.0 and higher, this dependency configuration no longer packages the lint checks in yourAndroid Library projects. To include lint check dependencies in yourAARlibraries, use thelintPublishconfiguration described below.

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

lintPublish

Use this configuration inAndroid library projectsto include lint checks you want Gradle to compile into alint.jarfile and package in yourAAR.

在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 toall build variants. If you instead want to declare a dependency foronly a specific build variant source setor for a testing source set, you mustcapitalize the configuration nameandprefix it with the name of the build variantor 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 thatcombines a product flavor and a build type, then you must initialize theconfiguration namein theconfigurationsblock. 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 yourlocal testsandinstrumented 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 supportsandroid-aptplugin.

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

Pass arguments to annotation processors

If you need to pass arguments to an annotation processor, you can do so using theannotationProcessorOptionsblock in your module's build configuration. For example, if you want to pass primitive data types as key-value pairs, you can use theargumentproperty, 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'sCommandLineArgumentProviderinterface.

但是,使用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 themodule'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 implementingCommandLineArgumentProviderhelps improve build performance, readCaching Java projects

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

Disable the annotation processor error check

If you have dependencies on thecompile classpaththat 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 thecompile classpathare still not added to theprocessor classpath.

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

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

If you experience issues after migrating your project'sannotation processorsto theprocessor classpath, you can allowannotation processorson thecompile classpathby 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 thatautomatically matches variantswhen consuming a library. This means an app'sdebugvariant automatically consumes a library'sdebugvariant, and so on. It also works when using flavors — an app'sfreeDebugvariant will consume a library'sfreeDebugvariant.

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

In order for the plugin to accurately match variants, you need to providematching fallbacksfor instances where adirect 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 adirect 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 tovariant-aware dependency matching.

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

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

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

Specifiesa sorted list of fallback build typesthat the plugin should try to usewhen 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 tospecify alternative matchesfor 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 whena 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 givenflavor dimensionthat exists in both the app and its library dependency, your app includesflavorsthat 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" flavorsfor the same dimension.

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

UsematchingFallbackstospecify alternative matchesfor theapp's "free" product flavor, as shown below:

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

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

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

Specifies asorted list of fallback flavorsthat the plugin should try to use when adependency'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 givenflavor dimensionthat exists in both the app and its library dependencies, there is no issue whena 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 aflavor dimensionthat 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”版本。

UsemissingDimensionStrategyin thedefaultConfigblock 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 theproductFlavorsblock, so each flavor can specify a different matching strategy for a missing dimension.

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

Specifies asorted list of flavorsthat the plugin should try to use from a givendimension. 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 amissingDimensionStrategyproperty foreach dimensionthat exists in a local dependency but not in your app.

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

You can override the default selection at theproduct flavorlevel by configuring anothermissingDimensionStrategyproperty 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 whenyour app includes a flavor dimension that a library dependency does not. That's because the pluginmatches 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 therepositoriesblock of your build.gradle file.

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

The order in which you list each repositorydeterminesthe order in which Gradle searches the repositories for eachproject 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 specifiesGoogle's Maven repositoryand JCenter as repository locations in the project's top-levelbuild.gradlefile, as shown below:

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

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

If you want something from theMaven centralrepository, then addmavenCentral(), or for a local repository usemavenLocal():

如果你想要 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 theGradle 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 atGoogle's Maven repository index(see below forprogrammatic access).

添加Google的Maven中提供的library

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

要在构建中添加其中一个库,请在顶级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 librariesandyour 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 theGoogle Maven repository(usually older library versions), you must download the offlineGoogle Repositorypackage from theSDK Manager. Then you can add these libraries to yourdependenciesblock 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 thatresources are mergedormanifest elements are mergedinto 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, seeMerge multiple manifest files.

查看依赖关系树

[View the dependency tree]

Somedirect dependenciesmay have dependencies of their own. These are calledtransitive dependencies. Rather than requiring you to manually declare each transitive dependency, Gradleautomatically gathers and addsthem for you.

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

Tovisualizeboth thedirect and transitive dependenciesof your project, the Android plugin for Gradle provides a Gradle task that generates a dependency tree for eachbuild variantandtesting source set.

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

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

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

Gradle 翻译 build dependencies 依赖 [MD]第1张

The following sample output shows thedependency treefor thedebugbuild 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 aboutmanaging dependenciesin Gradle, seeDependency management basicsin the Gradle User Guide.

解决重复的类错误

[Resolve duplicate class errors]

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

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

To help youinvestigatewhich dependencies are contributing to errors,inspect your app's dependency treeand look for dependencies that appear more than once or withconflicting versions.

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

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

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

  • SelectNavigate > Classfrom the menu bar.
  • In the pop-up search dialog, make sure that the box next toInclude non-project itemsis checked.
  • Type键入 the name of the class that appears in the build error.
  • Inspect检查 the results for the dependencies that include the class.

Gradle 翻译 build dependencies 依赖 [MD]第2张The following sections describe thedifferent types of dependency resolution errorsyou may encounter and how to fix them.

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

修复重复class错误

Fix duplicate class errors

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

Program type already present com.example.MyClass

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

  • Abinary dependencyincludes alibrarythat yourappalso includes as adirect 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 alocal binary dependencyand aremote binary dependencyon the same library.

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

修复classpaths之间的冲突

Fix conflicts between classpaths

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

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

Your app'sruntime classpathalso determines the version numbers that Gradle requires for matching dependencies in theruntime classpathfor the app's test APK. Thehierarchyof classpaths is described in figure 1.

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

Gradle 翻译 build dependencies 依赖 [MD]第3张

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

A conflict wheredifferent versions of the same dependency appears across multiple classpathsmigh occur when, for example, your app includes a version of a dependency using theimplementationdependency configuration and a library module includesa different version of the dependencyusing theruntimeOnlyconfiguration.

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

When resolving dependencies on yourruntime and compile time classpaths, Android Gradle plugin 3.3.0 and higher attempt toautomatically fix certain downstream version conflicts. For example, if theruntime classpathincludes Library A version 2.0 and thecompile classpathincludes Library A version 1.0, the plugin automatically updates the dependency on thecompile classpathto Library A version 2.0 to avoid errors.

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

However, if theruntime classpathincludes Library A version 1.0 and thecompile classpathincludes Library A version 2.0, the plugin does notdowngradethe dependency on thecompile classpathto 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 anapidependency to yourlibrary module. That is,only your library module declares the dependency, but theapp modulewill also have access to its API, transitively.

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

  • Alternatively, you can declare the dependency inboth modules, but you should make sure that each module uses the same version of the dependency. Consider configuringproject-wide propertiesto ensure versions of each dependencyremain consistent保持一致 throughout your project.

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

应用自定义构建逻辑

[Apply custom build logic]

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

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

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

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

Publish variant dependencies to custom logic

A library can havefunctionalitiesthat other projects or sub-projects might want to use.Publishinga library is theprocessby 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 thetransitive dependenciesof each classpath which must be used by consumers to consume the library as described below:

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

  • variant_nameApiElements: This configuration holds thetransitive dependenciesthat are available to consumers atcompile time.
  • variant_nameRuntimeElements: This configuration holds thetransitive dependenciesthat are available to consumers atruntime.

To learn more about the relationships between the different configurations, go toThe 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 Atransitivelydepends on version 3 of module B, therearisesa dependency version conflict.

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

To resolve this conflict, the Android Gradle Plugin uses the followingdependency resolution strategy: when the plugindetectsthat different versions of the same module are in thedependency 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 thedependency resolution strategy, use the following configurations to resolve specific dependencies of a variant that are needed for your task:

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

  • variant_nameCompileClasspath:This configuration contains theresolution strategyfor a given variant’scompile classpath.
  • variant_nameRuntimeClasspath:This configuration contains theresolution strategyfor a given variant’sruntime classpath.

The Android Gradle plugin includesgettersthat you can use to access theconfiguration objects of each variant. Thus, you can use thevariant APIto query thedependency resolutionas 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

免责声明:文章转载自《Gradle 翻译 build dependencies 依赖 [MD]》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇WINCE USB驱动组入RocketMQ安装下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

statement 、prepareStatement的用法和解释

转自:http://blog.csdn.net/QH_JAVA/article/details/48245945 一、prepareStatement 的用法和解释 1.PreparedStatement是预编译的,对于批量处理可以大大提高效率. 也叫JDBC存储过程 2.使用 Statement 对象。在对数据库只执行一次性存取的时侯,用 Stateme...

GDB如何调试没有符号表(未加-g选项的编译)的程序

/********************************************************************* * Author  : Samson * Date    : 01/30/2015 * Test platform: *              3.13.0-24-generic *              G...

Linux根文件系统分析之init和busybox

Hi,大家好!我是CrazyCatJack。今天给大家讲解Linux根文件系统的init进程和busybox的配置及编译。 先简单介绍一下,作为一个嵌入式系统,要想在硬件上正常使用的话。它的软件组成大概有这三部分:1)bootloader 2)嵌入式系统kernel 3)根文件系统 。这其实非常好理解,类比于PC上的操作系统,首先我们需要类似BIOS的东东...

谷歌大神Jeff Dean:大规模深度学习最新进展 zz

http://www.tuicool.com/articles/MBBbeeQ 在AlphaGo与李世石比赛期间,谷歌天才工程师Jeff Dean在Google Campus汉城校区做了一次关于智能计算机系统的大规模深度学习(Large-Scale Deep Learning for Intelligent Computer Systems)的演讲。本文是...

gcc 编译器参数

一、GCC编译过程 参考:http://hi.baidu.com/zengzhaonong/item/c00e079f500adccab625314f-------------------------------------    Pre-Processing   cpp        预处理    Compiling        ccl       ...

curl 交叉编译 支持http2和openssl

touch run.sh chmod 755 run.sh mkdir build cd build ../run.sh run.sh #!/bin/bash #cd /build ../configure --host=aarch64-linux-android --with-ssl="/home/soft/openssl-1.1.1b/buil...