概述
gradle提高了android的工程化能力,它使得app的编译更加的灵活可控,今天我们主要来说说依赖三方库的那些事。
早期依赖
早期android项目都是单模块的,依赖关系在一起维护,所以不用考虑重复库导致的冲突问题。如下:
模块化依赖
随着工程越来越大,我们被迫将项目进行拆分,从之前的单模块的项目,升级成了多模块共同编译。随着模块化的进行,将会遇到不能模块依赖同一个库,一般为了保证依赖的版本一致,我们会在gradle.properties中定义版本号,并在gradle中进行引用。如下:
这其实不够优雅,因为前面的部分没有省略,多了很多没必要的样板代码。另外在实际执行过程中发现有人会定义两个版本key,比如:retrofit_version和version_retrofit因为确实不好匹配,其他人是否已经定义了这个版本号。
优雅的依赖
这是最终的依赖方式,对于模块的使用者而言,我为什么要关注这个三方库的版本号,我仅仅想使用它而已,而对于三方库的升级应该统一起来维护。
另外gradle的其他依赖方式也都可以用,配置也可以设:
思路
主要依赖于Groovy语言的动态性,可以动态的生成方法,如下:
实现
private def add(key, name, version, isFilter) {
Dependencies.dependenciesMap.each {
if (it.value.name.equals(name)) {
println("重复依赖==>" + name)
throw new RuntimeException("重复依赖==>" + name)
}
if (it.key.equals(key)) {
println("重复key定义==>" + key)
throw new RuntimeException("重复key定义==>" + key)
}
}
Dependencies de = new Dependencies(version, name, isFilter)
Dependencies.dependenciesMap.put(key, de)
project.metaClass.static."$key" = {
project.dependencies.implementation "$name:$version"
}
project.metaClass.static."${key}_api" = { params ->
if (params == null) {
project.dependencies.api "$name:$version"
} else {
project.dependencies.api("$name:$version", params)
}
}
project.metaClass.static."${key}_compileOnly" = { params ->
if (params == null) {
project.dependencies.compileOnly "$name:$version"
} else {
project.dependencies.compileOnly("$name:$version", params)
}
}
project.metaClass.static."${key}_releaseImplementation" = { params ->
if (params == null) {
project.dependencies.releaseImplementation "$name:$version"
} else {
project.dependencies.releaseImplementation("$name:$version", params)
}
}
project.metaClass.static."${key}_debugImplementation" = { params ->
if (params == null) {
project.dependencies.debugImplementation "$name:$version"
} else {
project.dependencies.debugImplementation("$name:$version", params)
}
}
}
def forceDependencies(configurations) {
configurations.all {
resolutionStrategy.cacheChangingModulesFor 0, 'seconds'
Dependencies.dependenciesMap.values().forEach {
resolutionStrategy.force "$it.name:$it.version"
}
}
}
def forceExcludeLib(phantomPluginConfig) {
Dependencies.dependenciesMap.values().forEach {
if (it.isFilter) {
phantomPluginConfig.excludeLib "$it.name:$it.version", true, ">=${it.version}"
}
}
}
ext {
forceDependencies = this.&forceDependencies
forceExcludeLib = this.&forceExcludeLib
}
class Dependencies {
static Map<String, Dependencies> dependenciesMap = new HashMap<>()
String version
String name
boolean isFilter
Dependencies(version, name, isFilter) {
this.version = version
this.name = name
this.isFilter = isFilter
}
}
Dependencies.dependenciesMap.clear()
add "v_pluginsdk", "com.wlqq.android:PluginSdk", "1.0.0", false
add "v_component_core", "com.ymm.lib:componentcore", "1.0.0", true
add "v_plugin_service", "com.ymm.lib:plugin-service", "1.0.0", true
后面添加库,可以在后面添加add 配置。另外,如果在项目中使用的话,建议单独维护一个配置文件(我们需要想办法将易变部分和不易变部分区分开)。