Gradle for Android(三) 依賴管理

依賴管理是Gradle的一個亮點。在最好的情況下,你只需要在構(gòu)建文件中添加一行代碼,Gradle就可以從遠程倉庫下載依賴并確??捎?。當(dāng)你所需的依賴還有它自己的依賴時,Gradle會自動接管這些事情。依賴的依賴稱為傳遞依賴(transitive dependencies)。

本章將介紹依賴管理的概念,并通過多種方式在Android工程中引入依賴。主要內(nèi)容有:

  • 倉庫
  • 本地依賴
  • 依賴的幾個概念

倉庫

我們所說的依賴通常是指外部依賴,比如其他開發(fā)者提供的庫。手動管理依賴是非常困難的事情。你需要找到這個庫,然后下載JAR包,并拷貝到工程中,最后再引用它。一般這些JAR包的名稱中并不包含版本信息,所以你需要自己添加,以便日后升級。你還需要確保這些庫保存在一個源管理系統(tǒng)中,這樣其他團隊成員才可以直接引用基礎(chǔ)代碼,而不需要手動去下載依賴。

使用倉庫可以解決這些問題。一個倉庫可以看做是一個文件集。Gradle默認不會為你的工程定義任何倉庫,所以你需要自己在repositories塊中添加。如果你使用的是Android Studio,它會幫你做這些。我們在前面的章節(jié)簡單提到了repositories塊,如下:

repositories {
    jcenter()
}

Gradle支持三種不同的倉庫:Maven、Ivy和靜態(tài)文件或者目錄。在構(gòu)建的execution期間,Gradle會從倉庫中獲取這些依賴。Gradle同樣會保存一個本地的緩存,這樣同一個版本的依賴只會下載一次。

一個依賴由三個元素定義:

  • group指明了創(chuàng)建這個倉庫的組織,通常是域名的翻轉(zhuǎn)。
  • name是倉庫的唯一標識
  • version指定倉庫的版本

基于這三個元素,一個依賴可以在dependencies塊中這樣聲明:

dependencies {
    compile 'com.google.code.gson:gson:2.3'
    compile 'com.squareup.retrofit:retrofit:1.9.0'
}

這是Groovy中map的一種簡寫,全寫如下:

dependencies {
    compile group: 'com.google.code.gson', name: 'gson', version:'2.3'
    compile group: 'com.squareup.retrofit', name: 'retrofit', version: '1.9.0'
}

一個依賴的必需元素是name,groupversion是可選的。盡管如此,我們?nèi)越ㄗh添加上group以使依賴變得清晰,添加上version,這樣可以確保依賴不會自動更新,否則會打斷構(gòu)建。

預(yù)置倉庫

為了方便,Gradle預(yù)置了三個Maven倉庫:JCenter,Maven Central和本地Maven倉庫??梢蕴砑尤缦麓a來引入它們:

repositories {
    mavenCentral()
    jcenter()
    mavenLocal()
}

Maven Central和JCenter是兩個廣泛使用的在線倉庫。你不必同時使用它們,我們推薦使用JCenter,這也是Android Studio創(chuàng)建的Android工程的默認倉庫。JCenter是Maven Central的父集,所以當(dāng)你做開關(guān)的時候,你可原封不動的保留已定義的依賴項。在此之上,它還支持HTTPS,這和Maven Central不同。

本地Maven倉庫是一個你所使用的所有依賴的本地緩存,你也可以添加你自己的依賴。默認情況下,這個倉庫在home目錄的.m2文件夾下。在Linux或者Mac OS X中,路徑為~/.m2,Windows中為%UserProfile%\.m2。

除了預(yù)置的倉庫,你也可以添加其他公有的或者私有的倉庫。

遠程倉庫

有些組織創(chuàng)建有趣的插件或者倉庫,并且傾向于將它們部署在自己的Maven或者Ivy服務(wù)器上。為了將它們添加到你的構(gòu)建中,你只需要在maven塊中添加URL地址:

repositories {
    maven {
        url "http://repo.acmecorp.com/maven2"
    }
}

這同樣適用于Ivy倉庫。Apache Ivy在Ant中是一個流行的依賴管理者。Gradle以與Maven庫相同的格式支持這些倉庫。

repositories {
    ivy {
        url "http://repo.acmecorp.com/repo"
    }
}

如果你的組織有自己的倉庫,需要有證書才可以訪問,可以這樣寫:

repositories {
    maven {
        url "http://repo.acmecorp.com/maven2"
        credentials {
            username 'user'
            password 'secretpassword'
        }
    }
}

Maven和Ivy使用同樣的方式。

保存證書
在構(gòu)建文件中保存證書不是一個好主意。構(gòu)建文件是純文本的,并被檢入源控制系統(tǒng)。更好的方式是使用單獨的Gradle properties文件來保存,就像我們在第二章看到的那樣。

本地倉庫

在你的硬盤或者網(wǎng)盤上運行Maven或者Ivy倉庫是可行的。為將其添加到你的構(gòu)建中,你只需要配置一個相對或者絕對的URL地址:

repositories {
    maven {
        url "../repo"
    }
}

新建的Android工程,默認依賴Android Support Library。在使用SDK Manager安裝Google倉庫時,會在你的硬盤上創(chuàng)建兩個Maven倉庫:ANDROID_SDK/extras/google/m2repositoryANDROID_SDK/extras/android/m2repository。這是Gradle獲取Google提供的庫的地址,比如:Android Spport Library和Google Play Services。

你也可以使用flatDirs添加一個常規(guī)目錄作為倉庫。它允許你在dependency塊中從該目錄添加文件。

repositories {
    flatDir {
        dirs 'aars'
    }
}

本章的后續(xù)內(nèi)容中,在講解庫工程時, 我們會看一個使用它的例子。

本地依賴

某種情況下,你可能仍需要手動下載Jar包或者native庫?;蛟S你想創(chuàng)建你自己的倉庫,這樣就可以在多個工程中重復(fù)使用它,而且不必將他發(fā)布到公有或者私有的倉庫中。在這種情況下,不可能去使用任何在線的資源,你需要使用其他的方式來添加依賴。我們會講述如何使用文件依賴,如何包含native庫,以及如何在你的工程中引用庫工程。

文件依賴

你可以使用files方法來添加一個Jar文件依賴

dependencies {
    compile files('libs/domoarigato.jar')
}

文件過多時,你可以添加文件夾:

dependencies {
    compile fileTree('libs')
}

默認情況下,新建的Android工程有一個libs目錄,并且被添加為依賴目錄。你還可以添加過濾器,只添加Jar包為依賴:

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

這意味著在Android Studio創(chuàng)建的任何工程中,你可以在libs文件夾下放置Jar包,它會被自動包含在編譯路徑和最終的APK中。

Native庫

用C或C++編寫的庫可以編譯成特定平臺的native代碼。這些庫由幾個.so文件組成,每個文件對應(yīng)一個平臺。Android 插件默認支持native庫,你只需要在模塊中創(chuàng)建jniLibs目錄,并且為每個平臺創(chuàng)建相應(yīng)的子目錄就可以了。最后把.so文件放入對應(yīng)的子目錄。

結(jié)構(gòu)如下:

app
├── AndroidManifest.xml
└── jniLibs
    ├── armeabi
    │    └── nativelib.so
    ├── armeabi-v7a
    │    └── nativelib.so
    ├── mips
    │    └── nativelib.so
    └── x86
         └── nativelib.so

如果這個規(guī)則對你不適用,你可以在構(gòu)建文件中自定義目錄:

android {
    sourceSets.main {
        jniLibs.srcDir 'src/main/libs'
    }
}

庫工程

如果你想分享一個使用了Android API或者包含Android資源的庫,你需要創(chuàng)建一個庫工程。庫工程和應(yīng)用工程大體相同。你可以使用同樣的任務(wù)來構(gòu)建和測試庫工程,它們同樣可以有不同的構(gòu)建變體。不同的是輸出。應(yīng)用工程會生成一個APK,它可以安裝和運行在Android設(shè)備上;庫工程會生成一個.aar文件,該文件可以作為Android應(yīng)用工程的庫。

創(chuàng)建和使用庫工程模塊

在構(gòu)建腳本中,使用Android庫插件來代替Android應(yīng)用插件:

apply plugin: 'com.android.library'

有兩種方式可以在你的應(yīng)用中包含一個庫工程。

  • 將其作為模塊包含在工程中
  • 創(chuàng)建一個.aar文件,該文件可以多個應(yīng)用中重復(fù)使用。

第一種方式需要將模塊添加到settings.gradle文件中,并將其作為應(yīng)用模塊的依賴。settings文件如下:

include ':app', ':library'

在這種情況下,庫模塊被稱為library,相應(yīng)的會有一個同名的文件夾。為了使用這個庫,需要在應(yīng)用模塊的build.gradle文件將其添加為依賴:

dependencies {
    compile project(':library')
}

這樣應(yīng)用模塊的類路徑將會包含庫的輸出。我們將在第五章詳細討論這個方法。

使用.arr文件

如果你想創(chuàng)建一個可以在不同Android應(yīng)用中重復(fù)使用的庫,你可以構(gòu)建一個.aar文件,然后將其作為依賴添加到工程中。構(gòu)建庫時,.aar文件會在模塊目錄的build/output/aar/文件夾下生成。為了使用它,你需要在應(yīng)用模塊中創(chuàng)建一個文件夾,將.aar文件拷貝其中,然后添加該目錄為倉庫。

repositories {
    flatDir {
        dirs 'aars'
    }
}

這樣每個被放置其中的文件都會被依賴。你可以如下引用這些依賴:

dependencies {
    compile(name:'libraryname', ext:'aar')
}

這樣Gradle就會添加libraryname.aar作為依賴。

依賴的幾個概念

這里有一些依賴相關(guān)的概念,值得了解一下。其中一個是configurations,它解釋了我們在本章用到的compile關(guān)鍵字。

Configurations

有時我們需要使用一些特定設(shè)備提供的SDK,比如某些廠商的藍牙SDK。為了編譯代碼,你需要將SDK添加到compile classpath中。但你并不需要將其包含在APK中,因為它已經(jīng)存在于設(shè)備上了。這時候依賴的配置就起作用了。

Gradle將依賴分成各種配置,由文件集命名。下面是Android應(yīng)用或者庫的標準配置:

  • compile
  • apk
  • provided
  • testCompile
  • androidTestCompile

compile配置是默認的,包含編譯main應(yīng)用所需的全部依賴。該配置中的依賴不僅包含在類路徑中,還包含在生成的APK中。

apk配置只會包含在APK中,不會包含在類路徑中。

providedapk相反。這兩種配置只接受JAR依賴項,試圖將庫工程加入其中會導(dǎo)致錯誤。

testCompileandroidTestCompile會添加測試所需的特定外部庫。這兩個配置可以添加測試框架,比如JUnit或者Espresso。它們只在運行測試相關(guān)任務(wù)的時候才會用到。你只想在測試APK中使用這些框架,而不是發(fā)布的APK中。

除了這些標準的配置,Android插件還會為每個構(gòu)建變體創(chuàng)建配置,比如debugCompile,releaseProvided等。如果你只想在debug版本添加一個日志框架,這將會非常有用。你會在第四章學(xué)習(xí)到更多。

語義版本控制

版本控制是依賴管理很重要的一個方面。添加到倉庫(如JCenter)的依賴被認為遵循一組版本控制規(guī)則,稱為語義版本控制。在語義版本控制下,版本號遵循major.minor.patch的規(guī)則,版本號的增長遵循如下規(guī)則:

  • major(主版本號)在API有不兼容的修改時增長
  • minor(小版本號)以向后兼容的方式添加功能時增長
  • patch(補?。?/strong>修改bug時增長

動態(tài)版本

某些情況下,你希望每次構(gòu)建應(yīng)用或者庫時都能獲得最新的依賴。最好的方式就是使用動態(tài)版本。下面是使用動態(tài)版本的幾種方式:

dependencies {
    //獲取最新的patch
    compile 'com.android.support:support-v4:22.2.+'
    //獲取最新的小版本號至少是2的小版本
    compile 'com.android.support:appcompat-v7:22.2+'
    //獲取最新版本
    compile 'com.android.support:recyclerview-v7:+'
}

你需要慎重使用動態(tài)版本。使用動態(tài)版本,Gradle可能會選擇不穩(wěn)定的版本,導(dǎo)致構(gòu)建失敗。更嚴重的是,構(gòu)建服務(wù)器和你的本地機器可能會使用不同版本的依賴,導(dǎo)致應(yīng)用的行為不一致。

在你使用動態(tài)版本時,Android Studio會給出警告。

Inside Android Studio

本節(jié)略過

依賴順序

配置文件中依賴的排列順序決定了優(yōu)先級的高低,排在前面的庫優(yōu)先級大于排在后面的庫。這個順序在資源合并和清單文件元素合并的時候非常重要。

比如,如果你的項目聲明如下:

  • 依賴于A和B,且A在B前面
  • A依賴于C和D,C在D前面
  • B依賴于C

那么,展開的依賴順序如下:

  1. A
  2. D
  3. B
  4. C

這個順序保證了A和B都可以覆寫C;D的優(yōu)先級高于B,因為A的優(yōu)先級高于B。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容