本文首發於微信公衆號「後廠村碼農」html
相關文章
Gradle核心思想(一)爲何如今要用Gradle?
Gradle核心思想(二)Gradle入門前奏
Gradle核心思想(三)Groovy快速入門指南
Gradle核心思想(四)看似無用,實則重要的Gradle Wrapper
Gradle核心思想(五)通俗易懂的Gradle插件講解
Gradle核心思想(六)自定義Gradle插件的三種方式
Android Gradle (一)Gradle的Android插件入門前端
本系列上一篇,我介紹了Gradle的Android插件的入門,這一篇來介紹一些Gradle進階的內容,固然進階內容很是多,這篇文章就總結一些相對重要的、經常使用的一些知識點,好比Gradle的簽名配置和依賴管理。java
在通常公司中,當團隊比較小的時候,App的簽名信息都是放到項目中的,甚至會上傳到github上,這樣作非常方便。但隨着團隊人數的增多,這樣作的風險會愈來愈大,由於簽名信息是重要的資源,這樣就不能將簽名上傳到github上,也就不該該在build.gradle中直接配置簽名。 主要有如下的幾種解決方法: 1.自定義一個簽名配置文件 2.本地~/.gradle/gradle.properties文件中配置簽名信息android
首先,在工程的目錄下新建一個文件夾,內部存儲簽名文件和簽名信息文件。簽名文件爲gradledemo.jks,簽名信息文件爲keystore.properties。keystore.properties中的配置以下所示。git
STORE_FILE=../signfiles/gradledemo.jks
KEY_ALIAS=gradle
STORE_PASSWORD=jinjiesanbuqu
KEY_PASSWORD=jinjiesanbuqu
複製代碼
固然不要忘了在.gitignore中將gradledemo.jks和keystore.properties忽略掉。接着在模塊build.gradle中進行配置,若是還不清楚什麼是模塊build.gradle和項目build.gradle,看Android Gradle (一)Gradle的Android插件入門這篇文章。 在模塊build.gradle中加入以下代碼。程序員
apply plugin: 'com.android.application'
android {
...
}
def setSigningProperties(){
def propFile = file('../signfiles/keystore.properties')
if (propFile.canRead()){
def Properties props = new Properties()
props.load(new FileInputStream(propFile))
if (props!=null && props.containsKey('STORE_FILE') && props.containsKey('STORE_PASSWORD') &&props.containsKey('KEY_ALIAS') && props.containsKey('KEY_PASSWORD')) {
android.signingConfigs.release.storeFile = file(props['STORE_FILE'])
android.signingConfigs.release.storePassword = props['STORE_PASSWORD']
android.signingConfigs.release.keyAlias = props['KEY_ALIAS']
android.signingConfigs.release.keyPassword = props['KEY_PASSWORD']
} else {
throw new Exception("some key missing")
}
}else {
throw new Exception("keystore.properties not found:" + propFile.absolutePath)
}
}
複製代碼
setSigningProperties方法用於讀取keystore.properties文件中的簽名文件的信息。 最後在模塊build.gradle中的signingconfigs塊中調用setSigningProperties方法就能夠了。github
apply plugin: 'com.android.application'
android {
...
signingConfigs {
release {
setSigningProperties()
}
}
}
複製代碼
還能夠將簽名文件和簽名信息文件放到本地中。好比簽名文件放到~/.gradle/gradledemo.jks,簽名信息文件放到~/.gradle/keystore.properties。這樣簽名文件和簽名信息文件都不會提交到github上。 keystore.properties的內容以下。bash
GRADLEDOME_RELEASE_STORE_FILE=~/.gradle/release-key.keystore
GRADLEDOM_RELEASE_KEY_ALIAS=key-alias
GRADLEDOM_RELEASE_STORE_PASSWORD=pass
GRADLEDOM_RELEASE_KEY_PASSWORD=pass
複製代碼
在模塊build.gradle中的signingconfigs塊中配置簽名,以下所示。服務器
signingConfigs {
release {
storeFile file(GRADLEDOME_RELEASE_STORE_FILE) storePassword GRADLEDOME_RELEASE_STORE_PASSWORD keyAlias GRADLEDOME_RELEASE_KEY_ALIAS keyPassword GRADLEDOME_RELEASE_KEY_PASSWORD } } 複製代碼
除了這兩點,還能夠將簽名文件和簽名信息文件放在專門打包的服務器上,在打包的時候讀取便可。這個涉及的內容就多了,就不在本文進行說明了。微信
如今一個Android項目都是須要去引入其餘的庫,好比jar、aar、Module等等,如今咱們分別來介紹下。下面例子的代碼若是不特地說明均是寫在模塊build.gradle中的。 Gradle的本地庫依賴 關於jar依賴能夠按照以下這麼寫,能夠指定一個也能夠指定多個jar。
//依賴引入libs下全部的jar
implementation fileTree(dir:'libs',include:['*.jar']) //指定依賴某一個或幾個jar implementation files('libs/XXX.jar','libs/XXX.jar') 複製代碼
aar依賴須要額外增長一些語句,以下所示。
android {
...
repositories {
flatDir {
dirs "libs"
}
}
}
dependencies {
implementation fileTree(dir:'libs',include:['*.aar']) implementation(name:'XXX',ext:'aar') } 複製代碼
Gradle的本地Module依賴 當項目中有多個Module時,咱們須要在settings.gradle中引入,以下所示。
include ':app'
include ':library1', ':library2'
複製代碼
接着在模塊build.gradle引入。
implementation project(':library1') 複製代碼
Gradle的遠程庫依賴 當在Android Studio中新建一個項目時,會在項目build.gradle有以下代碼:
buildscript {
repositories {
google()
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:3.4.0'
}
}
allprojects {
repositories {
google()
jcenter()
}
}
複製代碼
這些代碼都是默認的,在buildscript和allprojects塊中,經過repositories來引入谷歌的Maven庫和JCenter庫。首先會從谷歌的Maven庫去尋找相應的庫,若是找不到會從JCenter庫中去尋找。 而後在模塊build.gradle加入以下的代碼,就能夠引入遠程庫。
implementation group:'com.android.support',name:'appcompat-v7',version:'28.0.0'
//簡寫
implementation 'com.android.support:appcompat-v7:28.0.0'
複製代碼
隨着Gradle依賴的庫愈來愈多,那麼必然會產生一些問題,好比依賴衝突的問題,爲了解決依賴衝突,咱們須要先了解Gradle的庫依賴管理的幾個技術點。
Gradle默認是支持依賴傳遞的,因此當用到Gradle依賴時必定會涉及到它,是必需要知道的一個知識點。 那什麼是依賴傳遞呢?舉一個最簡單的例子。 projectC依賴projectB,projectB依賴projectA,那麼projectC就依賴了projectA。 依賴傳遞會產生一些問題,好比重複依賴、依賴錯誤等問題,那麼咱們能夠經過transitive來禁止依賴傳遞。
implementation('com.xxx.xxx:xxx:3.6.3') {
transitive false
}
複製代碼
上面禁止了com.xxx.xxx:xxx:3.6.3庫的依賴傳遞,還可使用以下語句來關閉當前模塊的全部庫的依賴傳遞:
configurations.all {
transitive = false
}
複製代碼
只不過這樣就須要手動添加當前模塊的每一個庫的依賴項,通常不會這麼作。
有了依賴檢查,咱們能夠解決依賴產生的問題。依賴檢查有不少種方式,分別來介紹下。
使用Gradle的命令行 能夠直接使用Gradle的命令行來進行依賴檢查,拿Windows平臺來講,使用cmd進入項目的根目錄,執行gradle :app:dependencies便可,其中app是咱們新建工程時默認的模塊的名稱。日誌輸出不少,下面截取一部分:
+--- com.android.support:appcompat-v7:28.0.0
| +--- com.android.support:support-annotations:28.0.0 //1
| +--- com.android.support:support-compat:28.0.0 //2
| | +--- com.android.support:support-annotations:28.0.0
| | +--- com.android.support:collections:28.0.0
| | | \--- com.android.support:support-annotations:28.0.0
| | +--- android.arch.lifecycle:runtime:1.1.1
| | | +--- android.arch.lifecycle:common:1.1.1
| | | | \--- com.android.support:support-annotations:26.1.0 -> 28.0.0 //3
| | | +--- android.arch.core:common:1.1.1
| | | | \--- com.android.support:support-annotations:26.1.0 -> 28.0.0
| | | \--- com.android.support:support-annotations:26.1.0 -> 28.0.0
| | \--- com.android.support:versionedparcelable:28.0.0
| | +--- com.android.support:support-annotations:28.0.0
| | \--- com.android.support:collections:28.0.0 (*)
複製代碼
上面是appcompat-v7:28.0.0庫的依賴樹的一小部分,appcompat-v7:28.0.0依賴了註釋1處和註釋2的庫,註釋2處的庫又依賴了com.android.support:support-annotations:28.0.0和com.android.support:collections:28.0.0,所以當咱們引入appcompat-v7:28.0.0時,會自動下載全部它依賴傳遞的庫。註釋3處說明,Gradle在依賴傳遞時,會自動提高依賴傳遞的庫的版本,默認使用最高版本的庫。
使用Gradle面板 除了命令行,還可使用Android Studio中的右側的Gradle面板,找到app模塊,展開後找到help目錄中的dependencies,以下圖所示。
雙擊或者右鍵選擇第一個選項便可執行命令,日誌就會在AS中Run窗口中打印出來。 如今再舉個例子,拿咱們熟悉的retrofit舉例,在模塊build.gradle中引入retrofit:implementation 'com.squareup.retrofit2:retrofit:2.6.0'
複製代碼
執行依賴檢查命令,打印的關於retrofit的日誌以下:
+--- com.squareup.retrofit2:retrofit:2.6.0
| \--- com.squareup.okhttp3:okhttp:3.12.0
| \--- com.squareup.okio:okio:1.15.0
複製代碼
能夠很清楚看到retrofit:2.6.0依賴okhttp:3.12.0,而okhttp:3.12.0依賴okio:1.15.0。 這時咱們使用3.1小節的transitive試試,修改build.gradle:
implementation ('com.squareup.retrofit2:retrofit:2.6.0') {
transitive false
}
複製代碼
執行依賴檢查命令,打印的關於retrofit的日誌以下:
+--- com.squareup.retrofit2:retrofit:2.6.0
複製代碼
使用Gradle View插件 若是你以爲前兩種方式查看不方便、不直觀,還可使用Android Studio的Gradle View插件。 在AS中選擇File-->Settings-->Plugins中搜索gradle view,找到Gradle View插件安裝並重啓AS,以下圖所示。
接下來選擇View-–>Tools Windows--Gradle View,這時就能夠在AS的底部發現Gradle View窗口,裏面會顯示當前項目的全部依賴樹,以下圖所示。
依賴衝突產生的緣由可能是庫的版本問題,舉個例子,若是在build.gradle中這麼寫:
implementation 'com.squareup.retrofit2:retrofit:2.6.0'
implementation 'com.squareup.okio:okio:1.14.0'
複製代碼
在3.2小節中,咱們知道retrofit:2.6.0依賴的okio的版本是1.15.0,而這裏引入的okio的版本爲1.14.0,引入的版本不一樣就會產生依賴衝突。依賴衝突的解決的關鍵有兩點,一個是Gradle的依賴檢查,這個在3.2小節已經講過了,另外一個是利用Gradle的關鍵字,合理利用它們是解決依賴衝突的關鍵,在3.1小節已經介紹了 transitive,如今介紹其他的。
有時候咱們不是想要排除某個庫,而是須要強制使用統一的庫的版本,force能夠強制設置模塊的庫的版本,在模塊build.gradle中加入以下代碼。
configurations.all {
resolutionStrategy {
force 'com.squareup.okio:okio:2.1.0'
}
}
dependencies {
...
}
複製代碼
強制當前模塊的okio的版本爲2.1.0,使用依賴檢查來查看下retrofit的依賴:
+--- com.squareup.retrofit2:retrofit:2.6.0
| \--- com.squareup.okhttp3:okhttp:3.12.0
| \--- com.squareup.okio:okio:1.15.0 -> 2.1.0
\--- com.squareup.okio:okio:1.14.0 -> 2.1.0
複製代碼
能夠看到okio的版本都被強制升級到了2.1.0,這樣就能夠解決一些依賴衝突的問題。
有些時候須要排除庫依賴傳遞中涉及的庫,此時不能靠關閉依賴傳遞來解決問題,這時可使用exclude。 咱們知道com.android.support:appcompat-v7:28.0.0依賴於com.android.support:support-annotations:28.0.0、com.android.support:support-compat:28.0.0、com.android.support:cursoradapter:28.0.0等庫,這時咱們不想再依賴support-annotations庫,能夠這麼寫。
configurations {
all*.exclude group: 'com.android.support', module: 'support-annotations'
}
dependencies {
...
}
複製代碼
使用依賴檢查來查看com.android.support:appcompat-v7:28.0.0的依賴:
+--- com.android.support:appcompat-v7:28.0.0
| +--- com.android.support:support-compat:28.0.0
| | +--- com.android.support:collections:28.0.0
| | +--- android.arch.lifecycle:runtime:1.1.1
| | | +--- android.arch.lifecycle:common:1.1.1
| | | \--- android.arch.core:common:1.1.1
| | \--- com.android.support:versionedparcelable:28.0.0
| | \--- com.android.support:collections:28.0.0
| +--- com.android.support:collections:28.0.0
| +--- com.android.support:cursoradapter:28.0.0
複製代碼
和3.2節的日誌對比下,能夠發現com.android.support:appcompat-v7:28.0.0再也不依賴com.android.support:support-annotations:28.0,目的達到了。
感謝 www.jianshu.com/p/c602e6c49… blog.csdn.net/ouyang_peng… www.jianshu.com/p/82de510b4… blog.csdn.net/zjpp2580369… blog.fidroid.com/post/gradle…
更多的內容請關注個人獨立博客的知識體系:
liuwangshu.cn/system/
這裏不只分享大前端、Android、Java等技術,還有程序員成長類文章。