本文首发于微信公众号「后厂村码农」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,以下图所示。
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等技术,还有程序员成长类文章。