Gradle 翻譯 build dependencies 依賴 [MD]


博文地址

我的GitHub 我的博客 我的微信 我的郵箱
baiqiantao baiqiantao bqt20094 baiqiantao@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

此錯誤通常會在下列情況之一時發生:

  • 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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM