前言
這一篇來介紹一些Gradle進階的內容,當然進階內容非常多,這篇文章就總結一些相對重要的、常用的一些知識點,比如Gradle的簽名配置和依賴管理。
1.Android簽名文件配置
在一般公司中,當團隊比較小的時候,App的簽名信息都是放到項目中的,甚至會上傳到github上,這樣做很是方便。但隨著團隊人數的增多,這樣做的風險會越來越大,因為簽名信息是重要的資源,這樣就不能將簽名上傳到github上,也就不應該在build.gradle中直接配置簽名。
主要有以下的幾種解決方法:
1.自定義一個簽名配置文件
2.本地~/.gradle/gradle.properties文件中配置簽名信息
1.1 自定義簽名信息文件
首先,在工程的目錄下新建一個文件夾,內部存儲簽名文件和簽名信息文件。簽名文件為gradledemo.jks,簽名信息文件為keystore.properties。keystore.properties中的配置如下所示。
STORE_FILE=../signfiles/gradledemo.jksKEY_ALIAS=gradleSTORE_PASSWORD=jinjiesanbuquKEY_PASSWORD=jinjiesanbuqu
當然不要忘了在.gitignore中將gradledemo.jks和keystore.properties忽略掉。接著在模塊build.gradle中進行配置,如果還不清楚什么是模塊build.gradle和項目build.gradle,看寫給Android開發的Gradle知識體系這篇文章。
在模塊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方法就可以了。
apply plugin: 'com.android.application'android { ... signingConfigs { release { setSigningProperties() } }}
1.2 本地添加簽名信息文件
還可以將簽名文件和簽名信息文件放到本地中。比如簽名文件放到~/.gradle/gradledemo.jks,簽名信息文件放到~/.gradle/keystore.properties。這樣簽名文件和簽名信息文件都不會提交到github上。
keystore.properties的內容如下。
GRADLEDOME_RELEASE_STORE_FILE=~/.gradle/release-key.keystoreGRADLEDOM_RELEASE_KEY_ALIAS=key-aliasGRADLEDOM_RELEASE_STORE_PASSWORD=passGRADLEDOM_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 } }
除了這兩點,還可以將簽名文件和簽名信息文件放在專門打包的服務器上,在打包的時候讀取即可。這個涉及的內容就多了,就不在本文進行說明了。
2.Gradle的庫依賴
現在一個Android項目都是需要去引入其他的庫,比如jar、aar、Module等等,現在我們分別來介紹下。下面例子的代碼如果不特意說明均是寫在模塊build.gradle中的。
Gradle的本地庫依賴
關于jar依賴可以按照如下這么寫,可以指定一個也可以指定多個jar。
//依賴引入libs下所有的jarimplementation fileTree(dir:'libs',include:['*.jar'])//指定依賴某一個或幾個jarimplementation 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'
3.Gradle的庫依賴管理
隨著Gradle依賴的庫越來越多,那么必然會產生一些問題,比如依賴沖突的問題,為了解決依賴沖突,我們需要先了解Gradle的庫依賴管理的幾個技術點。
3.1 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}
只不過這樣就需要手動添加當前模塊的每個庫的依賴項,一般不會這么做。
3.2 Gradle的依賴檢查
有了依賴檢查,我們可以解決依賴產生的問題。依賴檢查有很多種方式,分別來介紹下。
使用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窗口,里面會顯示當前項目的所有依賴樹,如下圖所示。

3.3 Gradle的依賴沖突
依賴沖突產生的原因多是庫的版本問題,舉個例子,如果在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,現在介紹其余的。
3.3.1 force
有時候我們不是想要排除某個庫,而是需要強制使用統一的庫的版本,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,這樣就可以解決一些依賴沖突的問題。
3.3.2 exclude
有些時候需要排除庫依賴傳遞中涉及的庫,此時不能靠關閉依賴傳遞來解決問題,這時可以使用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,目的達到了。
原文:http://liuwangshu.cn/application/android-gradle/2-gradle-dependency.html作者:劉望舒來源:博客園