内容简介:上篇文章我们已经将Gradle基础运用介绍了一遍,可以这么说,只要你一直看了我这个Gradle系列,那么你的Gradle也将过关了,应对正常的工作开发已经不成问题了。这篇文章我要向你介绍的是关于如何使用Gradle来更加优雅的管理多个module之间的依赖关系。
上篇文章我们已经将Gradle基础运用介绍了一遍,可以这么说,只要你一直看了我这个Gradle系列,那么你的Gradle也将过关了,应对正常的工作开发已经不成问题了。
这篇文章我要向你介绍的是关于如何使用Gradle来更加优雅的管理多个module之间的依赖关系。
相信你一定有这样的经历:主项目依赖于多个子项目,或者项目间互相依赖。不同子项目间的依赖的第三方库版本又没有进行统一,升级一个版本所有依赖的项目都要进行修改;甚至minSdkVersion与targetSdkVersion也不相同。
今天我们就来解决这个问题,让Gradle版本管理更加优雅。
Google推荐
之前的文章 Android Gradle系列-运用篇 中的dependencies使用的是最基本的引用方式。如果你有新建一个kotlin项目的经历,那么你将看到Google推荐的方案
buildscript {
ext.kotlin_version = '1.1.51'
repositories {
google()
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:3.0.0'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
}
}
在rootProject的build.gradle中使用 ext 来定义版本号全局变量。这样我们就可以在module的build.gradle中直接引用这些定义的变量。引用方式如下:
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation"org.jetbrains.kotlin:kotlin-stdlib-jre7:$kotlin_version"
}
你可以将这些变量理解为 java 的静态变量。通过这种方式能够达到不同module中的配置统一,但局限性是,一但配置项过多,所有的配置都将写到rootProject项目的build.gradle中,导致build.gradle臃肿。这不符合我们的所提倡的模块开发,所以应该想办法将ext的配置单独分离出来。
这个时候我就要用到之前的文章 Android Gradle系列-原理篇 中所介绍的apply函数。之前的文章我们只使用了apply三种情况之一的plugin(应用一个插件,通过id或者class名),只使用在子项目的build.gradle中。
apply plugin: 'com.android.application'
这次我们需要使用它的 from ,它主要是的作用是 应用一个脚本文件 。作用接下来我们需要做的是将ext配置单独放到一个gradle脚本文件中。
首先我们在rootProject目录下创建一个gradle脚本文件,我这里取名为version.gradle。
然后我们在version.gralde文件中使用ext来定义变量。例如之前的kotlin版本号就可以使用如下方式实现
ext.deps = [:]
def versions = [:]
versions.support = "26.1.0"
versions.kotlin = "1.2.51"
versions.gradle = '3.2.1'
def support = [:]
support.app_compat = "com.android.support:appcompat-v7:$versions.support"
support.recyclerview = "com.android.support:recyclerview-v7:$versions.support"
deps.support = support
def kotlin = [:]
kotlin.kotlin_stdlib = "org.jetbrains.kotlin:kotlin-stdlib-jre7:$versions.kotlin"
kotlin.plugin = "org.jetbrains.kotlin:kotlin-gradle-plugin:$versions.kotlin"
deps.kotlin = kotlin
deps.gradle_plugin = "com.android.tools.build:gradle:$versions.gradle"
ext.deps = deps
def build_versions = [:]
build_versions.target_sdk = 26
build_versions.min_sdk = 16
build_versions.build_tools = "28.0.3"
ext.build_versions = build_versions
def addRepos(RepositoryHandler handler) {
handler.google()
handler.jcenter()
handler.maven { url 'https://oss.sonatype.org/content/repositories/snapshots' }
}
ext.addRepos = this.&addRepos
因为gradle使用的是groovy语言,所以以上都是groovy语法
例如kotlin版本控制,上面代码的意思就是将有个kotlin相关的版本依赖放到deps的kotlin变量中,同时deps放到了ext中。其它的亦是如此。
既然定义好了,现在我们开始引入到项目中,为了让所有的子项目都能够访问到,我们使用 apply from 将其引入到rootProject的build.gradle中
buildscript {
apply from: 'versions.gradle'
addRepos(repositories)
dependencies {
classpath deps.gradle_plugin
classpath deps.kotlin.plugin
}
}
这时build.gradle中就默认有了ext所声明的变量,使用方式就如dependencies中的引用一样。
我们再看上面的addRepos方法,在关于Gradle原理的文章中已经分析了repositories会通过RepositoryHandler来执行,所以这里我们直接定义一个方法来统一调用RepositoryHandler。这样我们在build.gradle中就无需使用如下方式,直接调用addRepos方法即可
//之前调用
repositories {
google()
jcenter()
}
//现在调用
addRepos(repositories)
另一方面,如果有多个module,例如有module1,现在就可以直接在module1中的build.gradle中使用定义好的配置
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
// support
implementation deps.support.app_compat
//kotlin
implementation deps.kotlin.kotlin_stdlib
}
上面我们还定义了sdk与tools版本,所以也可以一起统一使用,效果如下
android {
compileSdkVersion build_versions.target_sdk
buildToolsVersion build_versions.build_tools
defaultConfig {
applicationId "com.idisfkj.androidapianalysis"
minSdkVersion build_versions.min_sdk
targetSdkVersion build_versions.target_sdk
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
...
}
一旦实现了统一配置,那么之后我们要修改相关的版本就只需在我们定义的version.gradle中修改即可。无需再对所用的module进行逐一修改与统一配置。
BuildSrc&Kotlin
如果你的项目使用了kotlin,那么 buildSrc&Kotlin 的统一管理方案将更适合你。
Gradle项目会默认识别buildSrc目录,并且会将该目录中的配置注入到build.gradle中,以至于让build.gradle能够直接引用buildSrc中的配置项。
有了这一特性,我们就可以直接将之前version.gradle中的配置放入到buildSrc中,下面我们开始实现。
首先在根目录新建一个buildSrc目录(与app同级),然后在该目录新建src/main/java目录,该目录是你之后配置项所在的目录;同时再新建build.gradle.kts文件,并在该文件中添加kotlin-dsl
plugins {
`kotlin-dsl`
}
repositories {
jcenter()
}
之后再sync project,最终的目录结构如下
搭建好了目录,现在我们在src/main/java下使用kotlin新建Dependencies文件(文件名任意),在该文件中将之前的配置项放进来,只是使用kotlin语法进行实现而已,转化的代码如下
object Versions {
const val support = "26.1.0"
const val kotlin = "1.3.31"
const val gradle = "3.4.1"
const val target_sdk = 26
const val min_sdk = 16
const val build_tools = "28.0.3"
}
object Dependencies {
val app_compat = "com.android.support:appcompat-v7:${Versions.support}"
val kotlin_stdlib = "org.jetbrains.kotlin:kotlin-stdlib-jdk7:${Versions.kotlin}"
val kotlin_plugin = "org.jetbrains.kotlin:kotlin-gradle-plugin:${Versions.kotlin}"
val gradle_plugin = "com.android.tools.build:gradle:${Versions.gradle}"
val addRepos: (handler: RepositoryHandler) -> Unit = {
it.google()
it.jcenter()
it.maven { url = URI("https://oss.sonatype.org/content/repositories/snapshots") }
}
}
这时你就可以直接使用Dependencies与Versions在各个build.gradle中引用,例如app下的build.gradle
android {
compileSdkVersion Versions.target_sdk
buildToolsVersion Versions.build_tools
defaultConfig {
applicationId "com.idisfkj.androidapianalysis"
minSdkVersion Versions.min_sdk
targetSdkVersion Versions.target_sdk
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
...
}
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
// support
implementation Dependencies.app_compat
//kotlin
implementation Dependencies.kotlin_stdlib
}
根目录的build.gralde亦是如此
buildscript {
Dependencies.addRepos.invoke(repositories)
dependencies {
classpath Dependencies.gradle_plugin
classpath Dependencies.kotlin_plugin
}
}
allprojects {
Dependencies.addRepos.invoke(repositories)
}
task clean(type: Delete) {
delete rootProject.buildDir
}
其实我们真正需要get到的是一种思想,将配置统一管理。至于到底使用哪一种,这就看个人喜好了,但如果你的项目使用了kotlin,我还是建议你使用buildSrc模式,因为对于Groovy语法而言,我相信你还是对Kotlin更加熟悉。
源码地址: https://github.com/idisfkj/an...
如果想了解更多关于我的文章,可以扫描下方二维码,关注我的公众号~
以上所述就是小编给大家介绍的《Android Gradle系列-进阶篇》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
Music Recommendation and Discovery
Òscar Celma / Springer / 2010-9-7 / USD 49.95
With so much more music available these days, traditional ways of finding music have diminished. Today radio shows are often programmed by large corporations that create playlists drawn from a limited......一起来看看 《Music Recommendation and Discovery》 这本书的介绍吧!