Gradle 翻譯 build dependencies 依賴 MD

Markdown版本筆記 個人GitHub首頁 個人博客 個人微信 個人郵箱
MyAndroidBlogs baiqiantao baiqiantao bqt20094 baiqiantao@sina.com

目錄

添加構建依賴項

Add build dependencieshtml

Android Studio中的Gradle構建系統能夠輕鬆地將外部二進制文件其餘庫模塊做爲依賴項包含在構建中。依賴項能夠位於您的計算機上或遠程存儲庫中,而且它們聲明的任何傳遞依賴項[transitive dependencies]也會自動包含在內。java

此頁面描述瞭如何在Android項目中使用依賴項,僅包含特定於Android的Gradle插件[specific to the Android plugin for Gradle]的行爲和配置的詳細信息。android

依賴類型

Dependency typesgit

要向項目添加依賴項,請在build.gradle文件的dependencies塊中指定依賴項配置。github

app模塊的build.gradle文件包含如下三種不一樣類型的依賴項。編程

本地庫模塊依賴:project

Local library module dependencyapi

這聲明瞭對名爲「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文件的依賴。app

implementation fileTree(dir: 'libs', include: ['*.jar']) //指定目錄或知足規則的全部文件
implementation files('libs/foo.jar', 'libs/bar.jar') //指定單個文件

遠程二進制依賴

Remote binary dependency

示例中聲明瞭對 com.example.android 命名空間組[namespace group]內 app-magic 庫 12.3 版的依賴性。構建時,若是遠程二進制依賴的庫本地不存在,Gradle會在構建時從遠程站點中下載

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

依賴配置類型

Dependency configurations

dependencies 塊中,您可使用幾種不一樣的依賴項配置之一聲明庫依賴項。 每一個依賴項配置都爲Gradle提供了有關如何使用依賴項的不一樣說明。

implementation、api、compile 的區別
api 徹底等同於 compile,二者沒區別,你將全部的 compile 改爲 api時徹底沒有錯。

implementation 這個指令的特色就是,對於使用了該命令編譯的依賴,對該項目有依賴的項目將沒法訪問到使用該命令編譯的依賴中的任何程序,也就是將該依賴隱藏在內部,而不對外部公開。換句話說就是,使用 implementation 指令的依賴只做用於當前的 module,而不會傳遞

例如,有一個 module testsdk 依賴於 gson:implementation 'com.google.code.gson:gson:2.8.2'
另外一個 module app 依賴於 testsdk:implementation project(':testsdk')
這時候,由於 testsdk 使用的是 implementation 指令來依賴 gson,因此 app 裏邊不能引用 gson。

可是,若是 testsdk 使用的是 api 來引用 gson:api 'com.google.code.gson:gson:2.8.2'
則與 Gradle3.0.0 以前的 compile 指令的效果徹底同樣,app 的 module 也能夠引用 gson。

implementation

implementation 能夠認爲是功能精簡的 compile

Gradle將依賴項添加到編譯類路徑[compilation classpath],並將依賴項打包到構建輸出[packages the dependency to the build output]。 可是,當您的模塊配置 implementation 依賴項時,它讓Gradle知道,您不但願模塊在編譯時將依賴項泄露給其餘模塊(意思是在編寫代碼時不可見)。也就是說,依賴性僅在運行時(運行時是沒有分模塊的概念的,因此固然可見啦)可用於其餘模塊。

簡單來講就是,使用 implementation 時,對於引用此模塊的其餘模塊來講,在寫代碼時不可見(不能直接引用),可是在運行時能夠經過反射方式調用。

使用此依賴項配置而不是 api 或 compile,會減小構建時間,由於它減小了構建系統須要從新編譯的模塊數量。例如,若是一個 implementation 依賴項更改了其 API,那麼Gradle只會從新編譯依賴性和直接依賴於它的模塊。大多數 app 和 test 模塊都應使用此配置。

api

api 徹底等同於 compile

Gradle將依賴項添加到編譯類路徑並構建輸出。當一個模塊包含一個 api 依賴項時,它讓Gradle知道,該模塊想要將該依賴項傳遞給其餘模塊,以便它們在運行時和編譯時均可用

此配置的行爲與 compile 相似,但您應謹慎使用它,一般,你應當僅在須要將依賴項傳遞給上游使用者時使用。這是由於,若是 api 依賴項更改其外部 API,Gradle 在從新編譯時將從新編譯有權訪問該依賴項的全部模塊。所以,擁有大量的 api 依賴項會顯著增長構建時間。除非您但願將依賴項的 API 公開給單獨的模塊,不然模塊應該使用 implementation 依賴項。

compileOnly

compileOnly 與廢棄的 provided 徹底同樣

Gradle僅將依賴項添加到編譯類路徑,即,它不會添加到構建輸出中

這在如下狀況很是有用:您想建立一個 Android 模塊,而且在編譯期間須要依賴項,但在運行時其存在是可選的

若是使用此配置,則庫模塊必須包含運行時條件[runtime condition]以檢查依賴項是否可用,而後優雅的更改其行爲,以便在未提供時仍可正常運行。這有助於經過,不添加不重要的瞬態[transient]依賴項,來減少最終APK的大小。

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

runtimeOnly

runtimeOnly 與廢棄的 apk 徹底同樣

Gradle僅將依賴項添加到構建輸出,以便在運行時使用。也就是說,它不會添加到編譯類路徑中

annotationProcessor

annotationProcessor 能夠認爲是用於特定場景的 compile

要添加對做爲註釋處理器的庫的依賴關係,必須使用 annotationProcessor 配置將其添加到註釋處理器 classpath。這是由於使用此配置能夠經過將 compile classpath 與 annotationProcessor classpath 分開來提升構建性能

若是Gradle在編譯類路徑上找到註釋處理器,它將 deactivates compile avoidance,這會對構建時間產生負面影響(Gradle 5.0及更高版本,忽略在 compile classpath 上找到的註釋處理器)。

若是依賴項的JAR文件包含如下文件,則 Android Gradle Plugin 假定其是註釋處理器,:

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

若是插件檢測到編譯類路徑上的註釋處理器,則會產生構建錯誤。

lintChecks

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

使用此配置包括您但願Gradle在構建項目時執行的lint檢查。

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

注意:使用Android Gradle插件3.4.0及更高版本時,此依賴關係配置再也不在您的Android庫項目中打包lint檢查。 要在AAR庫中包含lint檢查依賴項,請使用下面描述的lintPublish配置。

lintPublish

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

在Android庫項目中使用此配置,以包含您但願Gradle在AAR中編譯爲lint.jar文件和包的lint檢查。

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

這會致使使用AAR的項目也應用這些lint檢查。 若是您以前使用lintChecks依賴關係配置在已發佈的AAR中包含lint檢查,則須要遷移這些依賴關係,而不是使用lintPublish配置。

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

依賴配置

Dependency configurations

爲特定構建變體源集聲明依賴項:configurations

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

以上配置適用於全部構建變體。若是您只想爲特定的構建變體源集或測試源集聲明依賴項,則必須將配置名稱大寫,並在其前面加上構建變量或測試源集的名稱。

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

例如,要僅將 implementation 依賴項添加到 "free" 產品風味,它看起來像這樣:

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

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

可是,若是要爲組合 product flavor 和 build type 的變體添加依賴項,則必須在 configurations 塊中初始化配置名稱。 如下示例將 runtimeOnly 依賴項添加到"freeDebug"構建變體:

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

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

要爲本地測試和instrumented測試添加 implementation 依賴項,它看起來像這樣:

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

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

可是,某些配置在這種狀況下沒有意義。 例如,由於其餘模塊不能依賴於androidTest,因此若是使用androidTestApi配置,則會收到如下警告:
WARNING: Configuration 'androidTestApi' is obsolete廢棄 and has been replaced with 'androidTestImplementation'

添加註釋處理器:annotationProcessor

Add annotation processors

若是將註釋處理器添加到編譯類路徑中,您將看到相似於如下內容的錯誤消息:

Error: Annotation processors must be explicitly declared[顯式聲明] now.

要解決此錯誤,請使用 annotationProcessor 配置依賴關係,爲項目添加註釋處理器,如 dagger2 能夠按以下方式配置:

// Adds libraries defining annotations to only the compile classpath. 僅將定義註釋的庫添加到編譯類路徑
compileOnly 'com.google.dagger:dagger:version-number'
// Adds the annotation processor dependency to the annotation processor classpath. 將註釋處理器依賴項添加到註釋處理器類路徑
annotationProcessor 'com.google.dagger:dagger-compiler:version-number'

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

將參數傳遞給註釋處理器:argument

Pass arguments to annotation processors

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

若是須要將參數傳遞給註釋處理器,則可使用模塊的構建配置中的 annotationProcessorOptions 塊來執行此操做。例如,若是要將原始數據類型做爲鍵值對傳遞,則可使用argument屬性,以下所示:

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

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

可是,使用Android Gradle插件3.2.0及更高版本時,須要使用Gradle的 CommandLineArgumentProvider 接口傳遞表示文件或目錄的處理器參數。

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

使用 CommandLineArgumentProvider 容許您或註釋處理器做者,經過將增量構建屬性類型註釋應用於每一個參數,來提升增量和緩存乾淨構建的正確性和性能。

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

例如,下面的類實現了 CommandLineArgumentProvider 併爲處理器註釋了每一個參數。該示例還使用Groovy語言語法,並直接包含在模塊的 build.gradle 文件中。

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

注意:一般,註釋處理器做者提供此類或有關如何編寫此類的說明。 這是由於每一個參數都須要指定正確的構建屬性類型註釋才能按預期工做。

CommandLineArgumentProvider 示例

class MyArgsProvider implements CommandLineArgumentProvider {

    // Annotates each directory as either an input or output for the annotation processor.
    @InputFiles
    // Using this annotation helps Gradle determine which part of the file path should be considered during up-to-date checks.
    @PathSensitive(PathSensitivity.RELATIVE)
    FileCollection inputDir

    @OutputDirectory
    File outputDir

    // The class constructor sets the paths for the input and output directories.
    MyArgsProvider(FileCollection input, File output) {
        inputDir = input
        outputDir = output
    }

    // Specifies each directory as a command line argument for the processor.
    // The Android plugin uses this method to pass the arguments to the annotation processor.
    @Override
    Iterable<String> asArguments() {
        // Use the form '-Akey[=value]' to pass your options to the Java compiler.
        ["-AinputDir=${inputDir.singleFile.absolutePath}", "-AoutputDir=${outputDir.absolutePath}"]
    }
}

android {...}

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

在建立實現 CommandLineArgumentProvider 的類以後,須要使用 annotationProcessorOptions.compilerArgumentProvider 屬性初始化並將其傳遞給 Android 插件,以下所示。

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

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

禁用註釋處理器錯誤檢查:includeCompileClasspath

Disable the annotation processor error check

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

若是您對包含您不須要的註釋處理器的 compile classpath 具備依賴性,則能夠經過將如下內容添加到build.gradle文件來禁用錯誤檢查。 請記住,添加到 compile classpath 的註釋處理器仍未添加到 processor classpath 中。

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

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

若是在將項目的註釋處理器遷移到 processor classpath 後遇到問題,則能夠經過將 includeCompileClasspath 設置爲 true 來容許編譯類路徑上的註釋處理器。 可是,建議不要將此屬性設置爲 true,而且在未來的 Android 插件更新中將刪除執行此操做的選項。

排除傳遞依賴項:exclude

Exclude transitive dependencies

隨着應用程序的增加,它可能包含許多依賴項,包括直接依賴項和傳遞依賴項(應用程序導入的庫所依賴的庫)。 要排除再也不須要的傳遞依賴項,可使用 exclude 關鍵字,以下所示:

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

若是您須要從 tests 中排除某些傳遞依賴項,則上面顯示的代碼示例可能沒法按預期工做。這是由於 test configuration 擴展了模塊的 implementation 配置。 也就是說,當Gradle解析配置時,它始終包含 implementation 依賴性。

所以,要從 tests 中排除傳遞依賴性,必須在 execution 時執行此操做,以下所示:

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

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

注意:您仍然能夠在依賴項塊中使用exclude關鍵字,如「排除依賴項」部分中的原始代碼示例所示,以省略特定於測試配置但未包含在其餘配置中的傳遞依賴項。

使用變體感知依賴關係管理

Use variant-aware dependency management

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

Android插件3.0.0及更高版本包含一個新的依賴機制,能夠在使用庫時自動匹配變體。這意味着應用程序的debug變體會自動使用庫的debug變體,依此類推。它在使用flavor時也有效 - 應用程序的freeDebug變體將使用庫的freeDebug變體。

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

爲了使插件準確匹配變體,您須要爲沒法直接匹配的實例提供 matching fallbacks。假如你的應用//程序配置了一個名爲「staging」的構建類型,但其中一個庫依賴項卻沒有。當插件嘗試構建應用程序的「staging」版本時,它將不知道要使用的庫版本,您將看到相似於如下內容的錯誤消息:

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

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

該插件包含DSL元素,可幫助您控制Gradle應如何解決,沒法在應用程序和依賴項之間進行直接變體匹配的狀況。請參閱下表以肯定應使用哪一個DSL屬性來解決與變體感知依賴項匹配相關的某些構建錯誤。

app 包含依賴庫不包含的 buildTypes:matchingFallbacks

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

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

指定插件在依賴項不包含 staging 構建類型時,應嘗試使用的回退構建類型的排序列表。您能夠根據須要指定儘量多的回退,而且插件會選擇依賴項中可用的第一個構建類型。

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

例如,您的應用程序包含「staging」構建類型,但依賴項僅包括「debug」和「release」構建類型。

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

使用 matchingFallbacks 爲給定的構建類型指定替代匹配,以下所示:

// In the app's build.gradle file.
android {
    buildTypes {
        debug {...}
        release {...}//因爲依賴項已包含此構建類型,所以您無需在此處提供 matchingFallbacks
        stage {
            matchingFallbacks = ['debug', 'qa'] //指定當依賴項不包含此構建類型時,應嘗試使用的構建類型的排序列表
        }
    }
}

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

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

app 包含依賴庫不包含的 productFlavors:matchingFallbacks

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

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

例如,您的 app 及其庫依賴項都包含「tier」風格維度。可是,應用程序中的「tier」維度包括 "free" and "paid" 風格,但依賴項僅包括相同維度的 "demo" and "paid」 風格。

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

使用matchingFallbacks爲應用程序的「free」產品風格指定替代匹配,以下所示:

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

不要在defaultConfig塊中配置matchingFallbacks。相反,您必須在productFlavors塊中指定給定 roduct Flavors 的回退,以下所示。

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

指定當依賴項的匹配 dimension 不包含「free」風格時,插件應嘗試使用的後備風格的排序列表。您能夠根據須要指定儘量多的回退,而且插件會選擇依賴項的「tier」維度中可用的第一個flavor。

// In the app's build.gradle file.
android {
    defaultConfig{...} //不要在defaultConfig塊中配置matchingFallbacks,而要在具體的productFlavors中配置
    flavorDimensions 'tier' //風格維度
    productFlavors { //產品風格
        paid {
            dimension 'tier' //因爲依賴庫中風格維度tier下也有此productFlavors,所以無需提供matchingFallbacks
        }
        free {
            dimension 'tier' //因爲依賴庫中風格維度tier下沒有此productFlavors,所以須要提供matchingFallbacks
            matchingFallbacks = ['demo', 'trial'] //排序列表中指定的是【庫】中可能有的productFlavors
        }
    }
}

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

請注意,對於應用程序及其庫依賴項中存在的給定風味維度,當庫包含app不包含的 product flavor 時,不會出現問題。 那是由於插件根本不會從依賴中請求那種flavors。

依賴庫包括 app 不具備的 flavorDimensions:missingDimensionStrategy

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

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

例如,庫依賴項包括「minApi」維度的風格,但您的app僅包含「tier」維度的風格。所以,當您想要構建app的「freeDebug」版本時,該插件不知道是否使用依賴項的「minApi23Debug」或「minApi18Debug」版本。

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

在defaultConfig塊中使用missingDimensionStrategy指定插件應從每一個缺乏的維度中選擇的默認flavor,以下面的示例所示。 您還能夠覆蓋productFlavors塊中的選擇,所以每種flavor均可覺得缺乏的維度指定不一樣的匹配策略。

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

指定插件應嘗試從給定維度使用的排序樣式列表。 如下告訴插件,當遇到包含「minApi」維度的依賴項時,它應該選擇「minApi18」風格。您能夠包含其餘flavor名稱,以提供維度的回退的排序列表。

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

您應該爲本地依賴項中存在但不在應用程序中的每一個維度指定missingDimensionStrategy屬性。

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

您能夠經過爲「minApi」維度配置另外一個missingDimensionStrategy屬性來覆蓋產品風格級別的默認選擇。

// In the app's build.gradle file.
android {
    defaultConfig{
        missingDimensionStrategy 'minApi', 'minApi18', 'minApi23' //優先使用依賴庫 minApi 下的 minApi18
        missingDimensionStrategy 'abi', 'x86', 'arm64' //優先使用依賴庫 abi 下的 x86
    }
    flavorDimensions 'tier'
    productFlavors {
        free {
            dimension 'tier'
            missingDimensionStrategy 'minApi', 'minApi23', 'minApi18' //覆蓋默認配置
        }
        paid {...}
    }
}

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

請注意,當您的app包含庫依賴項不包含的flavor dimension時,不會出現問題。那是由於插件只匹配依賴項中存在的維度。 例如,若是依賴項不包含ABI的維度,則app的「freeX86Debug」版本將僅使用依賴項的「freeDebug」版本。

遠程存儲庫

Remote repositories

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

當您的依賴項不是本地庫或文件樹時,Gradle將在build.gradle文件的repositories塊中指定的任何聯機存儲庫中查找文件。

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

列出每一個存儲庫的順序決定了Gradle在每一個項目依賴項中搜索存儲庫的順序。例如,若是存儲庫A和B都須要使用一個依賴項,而且您首先列出A,則Gradle將從存儲庫A下載依賴項。

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

默認狀況下,新建的Android Studio項目將Google的Maven存儲庫和JCenter指定爲項目頂級build.gradle文件中的存儲庫位置,以下所示:

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

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

若是你想要 Maven central 存儲庫中的東西,那麼添加 mavenCentral(),或者對於本地存儲庫使用mavenLocal():

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

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

或者,您能夠按以下方式聲明特定的Maven或Ivy存儲庫:

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

For more information, see the Gradle Repositories guide.

谷歌的Maven存儲庫

Google's Maven repository

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

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

添加Google的Maven中提供的library

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

要在構建中添加其中一個庫,請在頂級build.gradle文件中包含Google的Maven存儲庫:

allprojects {
    repositories {
        google() //若是您使用的Gradle版本低於4.1,則必須使用【maven { url 'https://maven.google.com'}】
    }
}

而後將所需的庫添加到模塊的 dependencies 塊中。 例如,appcompat庫以下所示:

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

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

可是,若是您嘗試使用上述庫的舊版本,而且您的依賴項失敗,那麼它在Maven存儲庫中不可用,您必須從offline存儲庫獲取庫。

程序化訪問

[Programmatic access]

要以編程方式訪問Google的Maven工件,您能夠從 maven.google.com/master-index.xml 獲取工件組的XML列表。而後,對於任何 group,您能夠在如下位置查看其 library 的名稱和版本:

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

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

您還能夠在如下位置下載POM和JAR文件:

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

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

SDK Manager 中的離線存儲庫

Offline repository from SDK Manager

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

對於Google Maven存儲庫不可用的庫(一般是較舊的庫版本),您必須從SDK Manager下載脫機Google Repository包。而後,您能夠像日常使用的方式同樣將這些庫添加到依賴項塊中。

脫機庫保存在 android_sdk/extras/ 中。

依賴關係

依賴順序

Dependency order

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

列出依賴項的順序表示每一個依賴項的優先級:第一個庫的優先級高於第二個庫,第二個庫的優先級高於第三個庫,依此類推。 在合併資源或將清單元素從庫合併到您的應用程序中時,此順序很是重要。

例如,若是您的項目聲明如下內容:

  • 按順序依賴 LIB_A 和 LIB_B
  • 而且 LIB_A 按順序依賴於 LIB_C 和 LIB_D
  • LIB_B 也依賴於 LIB_C

而後,flat 依賴順序以下:LIB_A LIB_D LIB_B LIB_C
這能夠確保 LIB_A 和 LIB_B 均可以覆蓋 LIB_C;LIB_D的優先級仍然高於 LIB_B,由於 LIB_A 的優先級高於 LIB_B。

其實這個順序並非特別好理解

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

查看依賴關係樹

[View the dependency tree]

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

某些直接依賴關係可能具備本身的依賴關係。 這些被稱爲傳遞依賴。Gradle不會要求您手動聲明每一個傳遞依賴項,而是自動收集並添加它們。

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

爲了可視化項目的直接依賴性和傳遞性依賴性,Gradle的Android插件提供了一個Gradle任務,該任務爲每一個構建變體和測試源集生成依賴關係樹。

要運行任務,請執行如下操做:

  • 選擇 View > Tool Windows > Gradle(或直接單擊工具窗口欄中的「Gradle」窗體)。
  • 展開 AppName > Tasks > android > androidDependencies。雙擊執行Gradle任務後,應該會打開 Run 窗口以顯示輸出。

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

如下示例輸出顯示了調試版本構建變體的依賴關係樹,幷包含上一示例中的本地庫模塊依賴關係和遠程依賴關係。

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

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

解決重複的類錯誤

[Resolve duplicate class errors]

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

當您嚮應用程序項目添加多個依賴項時,這些直接和傳遞依賴項可能會相互衝突,Android Gradle Plugin嘗試優雅地解決這些衝突,可是一些衝突可能致使編譯時或運行時錯誤。

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

爲了幫助您調查哪些依賴項致使錯誤,請檢查應用程序的依賴關係樹,並查找出現屢次或存在衝突版本的依賴項。

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

若是您沒法輕鬆識別重複的依賴項,請嘗試使用Android Studio的UI搜索包含重複類的依賴項,以下所示:

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

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

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

修復重複class錯誤

Fix duplicate class errors

例如,若是一個類在 runtime classpath 上出現屢次,則會出現相似如下的錯誤:

Program type already present com.example.MyClass

此錯誤一般會在下列狀況之一時發生:

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

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

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

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

修復classpaths之間的衝突

Fix conflicts between classpaths

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

當Gradle解析編譯類路徑時,它首先解析運行時類路徑,並使用此結果來肯定應將哪些版本的依賴項添加到編譯類路徑中。換句話說,運行時類路徑肯定下游類路徑上相同依賴項所需的版本號。

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

您的應用程序的運行時類路徑還肯定了Gradle在應用程序測試APK的運行時類路徑中匹配依賴項所需的版本號。類路徑的層次結構如圖1所示。

Figure 1. Version numbers of dependencies that appear across multiple classpaths must match according to this hierarchy. 多個類路徑中出現的依賴關係的版本號必須根據此層次結構匹配。

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

例如,當您的app包含使用implementation依賴項配置的依賴項版本,而且庫模塊包含使用runtimeOnly配置的不一樣版本的依賴項時,會出現多個類路徑中出現相同依賴關係的不一樣版本的衝突。

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

在解析運行時和編譯時類路徑的依賴關係時,Android Gradle插件3.3.0及更高版本會嘗試自動修復某些下游版本衝突。例如,若是運行時類路徑包含庫A版本2.0而且編譯類路徑包含庫A版本1.0,則插件會自動將編譯類路徑的依賴性更新爲庫A版本2.0以免錯誤。

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

可是,若是運行時類路徑包含庫A版本1.0且編譯類路徑包含庫A版本2.0,則插件不會將編譯類路徑上的依賴項降級爲庫A版本1.0,而且仍會出現相似於如下內容的錯誤:

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

要解決此問題,請執行如下操做之一:

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

    將所需的依賴項版本做爲 api 依賴項包含在庫模塊中。也就是說,只有你的庫模塊聲明瞭依賴關係,但 app 模塊也能夠傳遞訪問它的API。

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

    或者,您能夠在兩個模塊中聲明依賴項,但應確保每一個模塊使用相同版本的依賴項。 考慮配置項目範圍的屬性,以確保每一個依賴項的版本在整個項目中保持一致。

應用自定義構建邏輯

[Apply custom build logic]

如下內容實際工做中尚未使用過

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

本節介紹了在擴展 Android Gradle 插件或編寫本身的插件時很是有用的高級主題。

將變體依賴項發佈到自定義邏輯

Publish variant dependencies to custom logic

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

庫中能夠具備其餘項目或子項目可能想要使用的功能。發佈庫是向其使用者提供庫的過程。庫能夠控制其消費者在編譯時和運行時能夠訪問的依賴項。

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

有兩個獨立的配置,用以保存每一個類路徑的傳遞依賴關係,消費者必須使用它們來使用庫,以下所述:

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

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

自定義依賴解析策略

[Custom dependency resolution strategies]

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

項目可能包括對同一庫的兩個不一樣版本的依賴,這可能致使依賴性衝突。例如,若是您的項目依賴於模塊A的版本1和模塊B的版本2,而且模塊A transitively 地依賴於模塊B的版本3,則會出現依賴版本衝突。

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

爲解決此衝突,Android Gradle Plugin使用如下依賴項解析策略:當插件檢測到同一模塊的不一樣版本在依賴關係圖中時,默認狀況下,它會選擇版本號最高的版本。

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

可是,此策略可能並不老是按您的意願運行。要自定義依賴項解析策略,請使用如下配置來解析任務所需的變體的特定依賴項:

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

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

Android Gradle插件包含可用於訪問每一個變體的配置對象的getter方法。 所以,您可使用 variant API 來查詢依賴項解析,以下例所示:

精簡版

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

完整版

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

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

2019-5-12

相關文章
相關標籤/搜索