天天看點

Gradle 翻譯 build dependencies 依賴 [MD]

博文位址

我的GitHub 我的部落格 我的微信 我的郵箱
baiqiantao bqt20094 [email protected]

目錄

  • 添加建構依賴項
    • 依賴類型
      • 本地庫子產品依賴:project
      • 本地二進制依賴:fileTree 和 files
      • 遠端二進制依賴
    • 依賴配置類型
      • implementation
      • api
      • compileOnly
      • runtimeOnly
      • annotationProcessor
      • lintChecks
      • lintPublish
    • 依賴配置
      • 為特定建構變體源集聲明依賴項:configurations
      • 添加注釋處理器:annotationProcessor
      • 将參數傳遞給注釋處理器:argument
      • CommandLineArgumentProvider 示例
      • 禁用注釋處理器錯誤檢查:includeCompileClasspath
      • 排除傳遞依賴項:exclude
    • 使用變體感覺依賴關系管理
      • app 包含依賴庫不包含的 buildTypes:matchingFallbacks
      • app 包含依賴庫不包含的 productFlavors:matchingFallbacks
      • 依賴庫包括 app 不具有的 flavorDimensions:missingDimensionStrategy
    • 遠端存儲庫
    • 谷歌的Maven存儲庫
      • 添加Google的Maven中提供的library
      • 程式化通路
      • SDK Manager 中的離線存儲庫
    • 依賴關系
      • 依賴順序
      • 檢視依賴關系樹
    • 解決重複的類錯誤
      • 修複重複class錯誤
      • 修複classpaths之間的沖突
    • 應用自定義建構邏輯
      • 将變體依賴項釋出到自定義邏輯
      • 自定義依賴解析政策

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檔案包含以下三種不同類型的依賴項。

Local library module dependency

這聲明了對名為“mylibrary”的Android庫子產品的依賴。此名稱必須與在

settings.gradle

檔案中定義為

include

的庫名稱比對。建構應用程式時,建構系統會編譯庫子產品并将生成的

AAR檔案

打包到APK中。

implementation project(":mylibrary") // 依賴目前目錄下的本地庫子產品
implementation project(":chat:mylibrary") //依賴目前目錄下 chat 目錄中的本地庫子產品
           

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 可以認為是功能精簡的 compile

Gradle将依賴項添加到編譯類路徑[compilation classpath],并将依賴項打包到建構輸出[packages the dependency to the build output]。 但是,當您的子產品配置 implementation 依賴項時,它讓Gradle知道,您不希望子產品在

編譯時

将依賴項洩露給其他子產品(意思是在編寫代碼時不可見)。也就是說,依賴性

僅在運作時

(運作時是沒有分子產品的概念的,是以當然可見啦)可用于其他子產品。

簡單來說就是,使用 implementation 時,對于引用此子產品的其他子產品來說,在寫代碼時不可見(不能直接引用),但是在

運作時

可以通過

反射

方式調用。

使用此依賴項配置而不是 api 或 compile,會減少建構時間,因為它減少了建構系統需要重新編譯的子產品數量。例如,如果一個 implementation 依賴項更改了其 API,那麼Gradle隻會重新編譯依賴性和直接依賴于它的子產品。大多數 app 和 test 子產品都應使用此配置。

api 完全等同于 compile

Gradle将依賴項添加到編譯類路徑并建構輸出。當一個子產品包含一個 api 依賴項時,它讓Gradle知道,該子產品想要将該依賴項傳遞給其他子產品,以便它們

在運作時和編譯時都可用

此配置的行為與 compile 類似,但您應謹慎使用它,通常,你應當僅在需要将依賴項傳遞給上遊使用者時使用。這是因為,如果 api 依賴項更改其外部 API,Gradle 在重新編譯時将

重新編譯有權通路該依賴項的所有子產品

。是以,擁有大量的 api 依賴項會顯著增加建構時間。除非您希望将依賴項的 API 公開給單獨的子產品,否則子產品應該使用 implementation 依賴項。

compileOnly 與廢棄的 provided 完全一樣

Gradle僅将依賴項添加到

編譯類路徑

,即,它

不會添加到建構輸出中

這在以下情況非常有用:您想建立一個 Android 子產品,并且

在編譯期間需要依賴項,但在運作時其存在是可選的

如果使用此配置,則庫子產品必須包含

運作時條件

[runtime condition]以檢查依賴項是否可用,然後優雅的更改其行為,

以便在未提供時仍可正常運作

。這有助于通過,不添加不重要的瞬态[transient]依賴項,來減小最終APK的大小。

注意:經測試發現,compileOnly不能傳遞依賴。

runtimeOnly 與廢棄的 apk 完全一樣

Gradle僅将依賴項添加到建構輸出,以便在運作時使用。也就是說,它

不會添加到編譯類路徑中

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
           

如果插件檢測到編譯類路徑上的注釋處理器,則會産生建構錯誤。

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配置。

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')
}
           

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 the

configuration 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

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'

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.

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.

注意:通常,注釋處理器作者提供此類或有關如何編寫此類的說明。 這是因為每個參數都需要指定正确的建構屬性類型注釋才能按預期工作。

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

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 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屬性來解決與變體感覺依賴項比對相關的某些建構錯誤。

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.

請注意,當庫依賴項包含您的應用程式不包含的建構類型時,沒有問題。 那是因為插件根本不會從依賴項中請求建構類型。

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 the

app'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。

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”版本。

missingDimensionStrategy

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都可以為缺少的次元指定不同的比對政策。

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 {...}
    }
}
           

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"

請注意,當您的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.

Google's Maven repository

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

  • Android Support Library
  • Architecture Components Library
  • Constraint Layout Library
  • AndroidX Test
  • Databinding Library
  • Android Instant App Library
  • Wear OS
  • Google Play services
  • Firebase

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

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

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

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

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.
Gradle 翻譯 build dependencies 依賴 [MD]

The following sections describe the

different types of dependency resolution errors

you may encounter and how to fix them.

以下部分描述了您可能遇到的不同類型的依賴項解析錯誤,以及如何解決這些錯誤。

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.

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所示。
Gradle 翻譯 build dependencies 依賴 [MD]

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

    transitive dependencies

    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

    resolution strategy

    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

繼續閱讀