Android Gradle (二)簽名配置和依賴管理

本文首發於微信公衆號「後廠村碼農」html

相關文章
Gradle核心思想(一)爲何如今要用Gradle?
Gradle核心思想(二)Gradle入門前奏
Gradle核心思想(三)Groovy快速入門指南
Gradle核心思想(四)看似無用,實則重要的Gradle Wrapper
Gradle核心思想(五)通俗易懂的Gradle插件講解
Gradle核心思想(六)自定義Gradle插件的三種方式
Android Gradle (一)Gradle的Android插件入門前端

前言

本系列上一篇,我介紹了Gradle的Android插件的入門,這一篇來介紹一些Gradle進階的內容,固然進階內容很是多,這篇文章就總結一些相對重要的、經常使用的一些知識點,好比Gradle的簽名配置和依賴管理。java

1.Android簽名文件配置

在通常公司中,當團隊比較小的時候,App的簽名信息都是放到項目中的,甚至會上傳到github上,這樣作非常方便。但隨着團隊人數的增多,這樣作的風險會愈來愈大,由於簽名信息是重要的資源,這樣就不能將簽名上傳到github上,也就不該該在build.gradle中直接配置簽名。 主要有如下的幾種解決方法: 1.自定義一個簽名配置文件 2.本地~/.gradle/gradle.properties文件中配置簽名信息android

1.1 自定義簽名信息文件

首先,在工程的目錄下新建一個文件夾,內部存儲簽名文件和簽名信息文件。簽名文件爲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()
        }
    }
}
複製代碼

1.2 本地添加簽名信息文件

還能夠將簽名文件和簽名信息文件放到本地中。好比簽名文件放到~/.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 } } 複製代碼

除了這兩點,還能夠將簽名文件和簽名信息文件放在專門打包的服務器上,在打包的時候讀取便可。這個涉及的內容就多了,就不在本文進行說明了。微信

2.Gradle的庫依賴

如今一個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'
複製代碼

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,以下圖所示。

eujYaq.png
雙擊或者右鍵選擇第一個選項便可執行命令,日誌就會在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,以下圖所示。

eujUiV.png

接下來選擇View-–>Tools Windows--Gradle View,這時就能夠在AS的底部發現Gradle View窗口,裏面會顯示當前項目的全部依賴樹,以下圖所示。

eujtI0.png

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,目的達到了。

感謝 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等技術,還有程序員成長類文章。

相關文章
相關標籤/搜索