Gradle Builds Everything —— 產物輸出

Gradle 打包的時候,還有個最終要的東西 —— 產物,這裏的產物包括提供給別的項目的產物,今天咱們來說一講,產物這個東西。
首先,看下咱們前面介紹了的 Configuration 對象,咱們看下這個接口聲明知道這個對象有incomingoutgoing兩種模式,incoming 咱們會用的多一點,就是從這個 Configuration 中獲取產物,好比:html

dependency {
    implementation `aa:bb:1.0.0`
    implementation `cc:dd:1.0.0`
}

那麼咱們可使用 project.getConfigurations().maybeCreate("implementation") 獲取到 implementation 相關的信息,同時使用getIncoming()拿到 ResolvableDependencies 對象,而後能夠調用getFiles()等直接拿到下載的文件。可是咱們前面知道,依賴下載來以後會根據一些規則作一些轉換,好比咱們使用的 aar 是不能直接參與編譯的,須要解壓,解出資源,class 文件,R.txt 等參與編譯,因此若是咱們想得到特定的類型,須要使用 artifactView 獲取一個視圖。java

Outgoing 和 Configuration 的關係

以上是 incoming 的用途,也就是 ResolvableDependencies,咱們如今要關注下 outgoing,就是 ConfigurationPublications,這個類用來註冊產物信息。api

在註冊產物前,咱們須要先定義一個 Configuration,由於 Configuration 裏面配置了 Attributes —— 這個類用來標註產物的一些屬性,只有過濾器對應上這個屬性以後,咱們才能獲取到相關的依賴。那麼咱們首先想一想兩個項目編譯
項目結構app

這樣的關係,咱們關注到 mylibrary 產出產物,成爲 Producer(P),app 消化 mylibrary 的產物,稱爲 Consumer(C)。gradle

Attribute 的定義

那麼這裏,咱們定義,P 和 C 都有一些屬性(Attribute),就像一對男女友同樣,只有對上眼了纔有可能互相選擇在一塊兒,他們互相挑選的方式就是使用 Attribute,在默認狀況下,只有 Attribute 「相符」的狀況下才能夠被 C 消費,那麼怎麼定義相符呢?首先默認的規則是這樣的:ui

  1. 若是 P 和 C 都擁有一個 attr name 相同的 attr,一旦 attr 的值不一致,則判斷爲不匹配。
  2. 若是 P 和 C 擁有對方沒有的 attr,那麼認爲他們依然匹配。

P 和 C 的 attr 能夠設置一些規則(Rule)來解決衝突和兼容問題,主要是 AttributeCompatibilityRule 和 AttributeDisambiguationRule 這兩個類。spa

C 去找 P 的過程就是僅僅是經過 Attribute 過濾找,沒有別的要素,那麼知道這個以後,咱們想讓 C 拿到咱們的結果的時候,只要讓 P 的 attribute 匹配上就行了。debug

綜上,咱們爲了避免污染 mylibrary 這個項目中其餘的 Conguration 的配置(每一個 Configuration 事實上就是一系列 配置的集合),咱們須要新建一個 Configuration。 Android Gradle Plugin 比較喜歡用 "apiElements" 和 "runtimeElements" 表明編譯時和運行時的依賴。code

debugApiElements

咱們把 Attribute 放大看全一點:orm

3.png

記住咱們剛剛的原則:

默認狀況下,若是有相關的屬性,值必定是同樣的。

我這裏截圖的是一個 application 工程,因此 AndroidTypeAttr 是 APK,若是是 AAR 的話,值就是 AAR。

咱們在 Consumer 裏面的 ArtifactView,先獲取到引入 mylibrary 的 Configuration 名稱,並設置以上的幾個 Attr,就能獲取到這個產物了。

Outgoing 產物設置

上面咱們簡單講了下 Attribute 和 Configuration 之間的關係,後續我會專門開篇講這個,所以咱們先點到爲止。
下面咱們講講 Outgoing 的用法:

runtimeConfig.getOutgoing()
    .variants(variants -> variants.create("xxxx-artifact", configurationVariant -> {
        configurationVariant.artifact(artifactFile, configurablePublishArtifact -> {
            configurablePublishArtifact.setType("jar"); 
            configurablePublishArtifact.builtBy(bundleArtifact);
        });
    }));

其中, configurationPublishAritfact 是 ConfigurablePublishArtifact 這個類,爲 artifactFile 這個文件定義了一些,具體能夠看下這個類的定義:https://docs.gradle.org/curre...

其中 setType 是設置這個文件的 artifactType,默認是文件的後綴名,若是咱們改爲其餘 Consumer 的 ArtfactTransfomer 產物類型的話,Consumer 就能省去 Transform 這一步,直接使用咱們導出的產物。

因此,從這裏咱們能夠知道,雖然 mylibrary 的最終產物是 aar,可是 app 依賴 mylibrary 的時候,是並不須要 aar 這個產物的,由於在 aar 打包以前,這些產物都已經存在,徹底沒有必要再解壓提取一次。

builtBy 這個是定義了產物的依賴,若是 app 在 task 執行階段須要提取這個產物的時候,就先要執行 builtBy 的這個 Task。

從這裏咱們終於知道了 app 的 task 和 mylibrary 的 task 是經過產物這條鏈連在一塊兒的。

結語

咱們經過本文知道了 Configuration Outing 的用途,後續會跟你們進行實戰項目解說,咱們來自定義一個 Configuration 和產物類型,敬請期待。

相關文章
相關標籤/搜索