Gradle for Android 第五篇( 多模組構建 )

segmentfault發表於2016-01-06

Android studio不僅允許你為你的app和依賴庫建立模組,同時也可為Android wear,Android TV,Google App Engine等建立模組,而這些單獨的模組又可以在一個單獨的專案中使用。舉個栗子,在你的app開發後期階段,你可能需要用到Google Clound或者Android Wear。這種情況下,你可以在你的工程下擁有三個模組:分別是app,google cloud,Android Wear整合。瞭解在一個工程下的多模組構建將會加速你的開發週期。

Gradle for Android 第一篇( 從 Gradle 和 AS 開始 )

Gradle for Android 第二篇( Build.gradle入門 )

Gradle for Android 第三篇( 依賴管理 )

Gradle for Android 第四篇( 構建變體 )

在這一章,我們將學習到多模組的構建,並且展示一些實際且有用的栗子:

  • 多模組構建的結構
  • 為你的專案新增模組
  • 建議

多模組構建的結構

通常情況下,一個工程包含多模組,這些模組會在一個父目錄資料夾下。為了告訴gradle,該專案的結構以及哪一個子資料夾包含模組,你需要提供一個settings.gradle檔案。每個模組可以提供其獨立的build.gradle檔案。我們已經學習了關於setting.gradle和build.gradle如何正常工作,現在我們只需要學習如何使用它們。

這是多模組專案的結構圖:

 project
   ├─── setting.gradle
   ├─── build.gradle
   ├─── app
   │    └─── build.gradle
   └─── library
        └─── build.gradle

這是最簡單最直接的方式來建立你的多模組專案了。setting.gradle檔案申明瞭該專案下的所有模組,它應該是這樣:

include ':app', ':library'

這保證了app和library模組都會包含在構建配置中。你需要做的僅僅只是為你的模組新增子資料夾。

為了在你的app模組中新增library模組做為其依賴包,你需要在app的build.gradle檔案中新增以下內容:

dependencies {
      compile project(':library') 
}

為了給app新增一個模組作為依賴,你需要使用project()方法,該方法的引數為模組路徑。

如果在你的模組中還包含了子模組,gradle可以滿足你得要求。舉個栗子,你可以把你的目錄結構定義為這樣:

project
├─── setting.gradle
├─── build.grade
├─── app
│    └─── build.gradle
└─── libraries
     ├─── library1
     │    └─── build.gradle
     └─── library2
          └─── build.gradle

該app模組依然位於根目錄,但是現在專案有2個不同的依賴包。這些依賴模組不位於專案的根目錄,而是在特定的依賴資料夾內。根據這一結構,你需要在settings.xml中這麼定義:

include ':app', ':libraries:library1', ':libraries:library2'

你會注意到在子目錄下申明模組也非常的容易。所有的路徑都是圍繞著根目錄,即當你新增一個位於子資料夾下的模組作為另外一個模組的依賴包得實惠,你應該將路徑定為根目錄。這意味著如果在上例中app模組想要依賴library1,build.gradle檔案需要這麼申明:

dependencies {
       compile project(':libraries:library1')
}

如果你在子目錄下申明瞭依賴,所有的路徑都應該與根目錄相關。這是因為gradle是根據你的專案的根目錄來定義你的依賴包的。

構建生命週期

理解了構建過程讓你理解多模組的構建變得容易。我們很早前談過關於構建的生命週期。所以現在你應該知道其基本的過程,但是一些很重要的細節可能你並不是很清楚。

在第一步驟中,即初始化階段,gradle會尋找到settings.grade檔案。如果該檔案不存在,那麼gradle就會假定你只有一個單獨的構建模組。如果你有多個模組,settings.gradle檔案定義了這些模組的位置。如果這些子目錄包含了其自己的build.gradle檔案,gradle將會執行它們,並且將他們合併到構建任務中。這就解釋了為什麼你需要申明在一個模組中申明的依賴是相對於根目錄。

一旦你理解了構建任務是如何將所有的模組聚合在一起的時候,那關於幾種不同的構建多模組策略就會變得簡單易懂。你可以配置所有的模組在根目錄下的build.gradle。這讓你能夠簡單的瀏覽到整個專案的配置,但是這將會變得一團亂麻,特別是當你的模組需要不同的外掛的時候。另外一種方式是將每個模組的配置分隔開,這一策略保證了每個模組之間的互不干擾。這也讓你跟蹤構建的改變變得容易,因為你不需要指出哪個改變導致了哪個模組出現錯誤等。

gradle的最大策略是混合。你可以在根目錄下定義一個build檔案去定義所有模組相同的熟悉,然後在每個模組中的build檔案去配置只屬於該模組的引數。Android studio遵循了該原則,其建立了一個build.gradle檔案在根目錄,然後再每個模組資料夾下建立了另外一個build檔案。

模組tasks

當你在你的專案中有多個模組的時候,你需要在執行任務之前想一想。當你在命令列介面執行一個task的時候,gradle將會找到哪個模組將會執行這個任務。舉個栗子,當你有個mobile app模組和一個Android Wear模組,你執行了gradlew assembleDebug任務。當你改變其中一個模組的資料夾位置,gradle將只會執行哪個特殊的模組,縱使你使用了gradle wrapper在根目錄。舉個栗子,當你執行../gradlew assembleDebug在Android wear模組的目錄下,其只會構建Android wear模組。

切換不同的資料夾去執行不同的任務會讓人很不爽,幸運的是,我們有其他的辦法。你可以準備一個特別的task來執行你的模組。舉個栗子,為了只構建Android Wear模組,你僅僅只需在根目錄下執行 gradlew :wear:assembleDebug。

為你的專案新增模組

在Android studio中新增新模組是很容易的一件事,該檢視同時也會為你建立build檔案。如下圖所示:

Gradle for Android 第五篇( 多模組構建 )

新增Java依賴庫

當你新建了一個Java模組,build.grade檔案會是這樣:

apply plugin: 'java'
   dependencies {
       compile fileTree(dir: 'libs', include: ['*.jar'])
}

Java模組使用了Java外掛,這意味著很多Android特性在這兒不能使用,因為你不需要。

build檔案也有基本的庫管理,你可以新增jar檔案在libs資料夾下。你可以新增更多的依賴庫,根據第三章的內容。

給你的app模組新增Java模組,這很簡單,不是嗎?

dependencies {
       compile project(':javalib')
}

這告訴了gradle去引入一個叫做javelin的模組吧,如果你為你的app模組新增了這個依賴,那麼javalib模組將會總是在你的app模組構建之前構建。

新增Android依賴庫

同樣的,我們利用Android studio的圖形化介面建立Android模組,然後其構建檔案如下:

apply plugin: 'com.android.library'

記住:Android依賴庫不僅僅包含了Java程式碼,同樣也會包含Android資源,像manifest和strings,layout檔案,在你引入該模組後,你可以使用該模組的所有類和資原始檔。

建議

我有點建議關於多模組專案,並且有些東西你們應該瞭解清楚,知道這些將會節約你們的時間。

在Android studio中執行模組tasks

當你有多個模組,Android studio會分析出來,並且展示在cradle中:

Gradle for Android 第五篇( 多模組構建 )

grade圖形化讓你執行模組間的任務變得簡單,但是其沒有為所有模組同時執行一個任務,所以如果你希望這麼做,最快的方式是使用命令列。

加速你的多模組構建

當你構建你的多模組專案,gradle會依次執行所有的模組。當你的電腦記憶體夠大的時候,讓你的構建過程多執行緒將會更快。該特性在gradle早已存在,但是其預設關閉。

所以如果你希望啟動parallel構建,你需要在grade.properties檔案中配置如下屬性:

org.gradle.parallel=true

gradle會選擇儘可能多的執行緒去執行你的構建過程,每個執行緒都會執行一個模組。parallel執行的是獨立的模組,即你的模組是獨立的。

模組耦合

即你可以在一個模組中引用其他模組的屬性,但是我不建議你們這麼做,我們完全可以在根目錄下的build檔案中定義這些屬性。

總結

我們學習瞭如何在一個專案中構建多個模組,以及新增新模組是如何影響到構建任務的執行。

我們學習了相關事例,並且給出了一些建議。

在下一章節,我們將會學習到測試,如何利用gradle讓你的測試更加簡單。我們將會學習到如何在jvm中執行你的單元測試,以及如何執行測試在你的手機上。

相關文章