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等技术,还有程序员成长类文章。

相关文章
相关标签/搜索