看了解决Android依赖冲突,学到了一些依赖分析并解决的方法。
-
run app仔细查看App的Build信息
2018-09-10_102515.png
很明显看到 错误发生在app:transformDexArchiveWithExternalLibsDexMergerForDebug这项任务
-
单独运行这项任务
在右侧 侧边栏gradle中找到这项任务,在app模块other目录下
2018-09-10_102835.png
直接运行
得到结果
2018-09-10_103112.png
可以看到 它有提示
Run with --stacktrace option to get the stack trace 来得到信息
-
在Setting->Build,Execution,Deployment->Compiler中的Command-line Opptions中输入–stacktrace启用堆栈跟踪
-
还可以在App的build.gradle中末尾加入
task allDeps(type: DependencyReportTask) {}
来查看依赖关系
统一管理版本号
在学习android的开源项目的时候,发现了他们的方式(versions.gradle)来管理版本号
-
建立versions.gradle
2018-09-10_143229.png -
如何引用到这个文件呢?
可以看到他在build.gradle中是这么写的
buildscript {
apply from: 'versions.gradle'
addRepos(repositories)
dependencies {
classpath deps.android_gradle_plugin
classpath deps.kotlin.plugin
classpath deps.kotlin.allopen
classpath deps.navigation.safe_args_plugin
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
}
- 分析它的versions.gradle文件
ext.deps = [:]
def versions = [:]
versions.arch_core = "1.1.1"
versions.room = "1.1.0"
versions.lifecycle = "1.1.1"
versions.support = "27.1.1"
versions.dagger = "2.15"
versions.junit = "4.12"
versions.espresso = "3.0.1"
...
def deps = [:]
def support = [:]
support.annotations = "com.android.support:support-annotations:$versions.support"
support.app_compat = "com.android.support:appcompat-v7:$versions.support"
support.recyclerview = "com.android.support:recyclerview-v7:$versions.support"
support.cardview = "com.android.support:cardview-v7:$versions.support"
support.design = "com.android.support:design:$versions.support"
support.v4 = "com.android.support:support-v4:$versions.support"
support.core_utils = "com.android.support:support-core-utils:$versions.support"
deps.support = support
...
def glide = [:]
glide.runtime = "com.github.bumptech.glide:glide:$versions.glide"
glide.compiler = "com.github.bumptech.glide:compiler:$versions.glide"
deps.glide = glide
deps.dexmaker = "com.linkedin.dexmaker:dexmaker-mockito:$versions.dexmaker"
deps.constraint_layout = "com.android.support.constraint:constraint-layout:$versions.constraint_layout"
deps.timber = "com.jakewharton.timber:timber:$versions.timber"
deps.junit = "junit:junit:$versions.junit"
deps.mock_web_server = "com.squareup.okhttp3:mockwebserver:$versions.mockwebserver"
deps.rxjava2 = "io.reactivex.rxjava2:rxjava:$versions.rxjava2"
deps.rx_android = "io.reactivex.rxjava2:rxandroid:$versions.rx_android"
deps.hamcrest = "org.hamcrest:hamcrest-all:$versions.hamcrest"
deps.android_gradle_plugin = "com.android.tools.build:gradle:$versions.android_gradle_plugin"
ext.deps = deps
def build_versions = [:]
build_versions.min_sdk = 14
build_versions.target_sdk = 26
build_versions.build_tools = "27.0.3"
ext.build_versions = build_versions
def work = [:]
work.runtime = "android.arch.work:work-runtime:$versions.work"
work.testing = "android.arch.work:work-testing:$versions.work"
work.firebase = "android.arch.work:work-firebase:$versions.work"
work.runtime_ktx = "android.arch.work:work-runtime-ktx:$versions.work"
deps.work = work
def navigation = [:]
navigation.runtime = "android.arch.navigation:navigation-runtime:$versions.navigation"
navigation.runtime_ktx = "android.arch.navigation:navigation-runtime-ktx:$versions.navigation"
navigation.fragment = "android.arch.navigation:navigation-fragment:$versions.navigation"
navigation.fragment_ktx = "android.arch.navigation:navigation-fragment-ktx:$versions.navigation"
navigation.safe_args_plugin = "android.arch.navigation:navigation-safe-args-gradle-plugin:$versions.navigation"
navigation.testing_ktx = "android.arch.navigation:navigation-testing-ktx:$versions.navigation"
deps.navigation = navigation
ext.deps = deps
def addRepos(RepositoryHandler handler) {
handler.google()
handler.jcenter()
handler.maven { url 'https://oss.sonatype.org/content/repositories/snapshots' }
}
ext.addRepos = this.&addRepos
我也没学过Groovy的语法,但是观察内容,一个是def的用法,一个是ext的用法,[:]是什么,带着问题来找答案
搜索可以得到一些结果
- 原来def是关键字
Groovy中支持动态类型,即 定义变量的时候可以不指定其类型 。Groovy中,变量定义可以使用关键字def。 注意,虽然def不是必须的,但是为了代码清晰,建议还是使用def关键字
- Groovy中的容器类很简单,就三种List,map,range
容器变量定义
变量定义:Map变量由[:]定义,比如
def aMap = ['key1':'value1','key2':true]
Map由[:]定义,注意其中的冒号。冒号左边是key,右边是Value。key必须是字符串,value可以是任何对象。另外,key可以用''或""包起来,也可以不用引号包起来。比如
def aNewMap = [key1:"value",key2:true] //其中的key1和key2默认被
处理成字符串"key1"和"key2"
不过Key要是不使用引号包起来的话,也会带来一定混淆,比如
def key1="wowo"
def aConfusedMap=[key1:"who am i?"]
aConfuseMap中的key1到底是"key1"还是变量key1的值“wowo”?显然,答案是字符串"key1"。如果要是"wowo"的话,则aConfusedMap的定义必须设置成:
def aConfusedMap=[(key1):"who am i?"]
Map中元素的存取更加方便,它支持多种方法:
println aMap.keyName <==这种表达方法好像key就是aMap的一个成员变量一样
println aMap['keyName'] <==这种表达方法更传统一点
aMap.anotherkey = "i am map" <==为map添加新元素
也就是定义了versions等map
- 额外属性ext
如果是单个脚本,则不需要考虑属性的跨脚本传播,
但是Gradle往往包含不止一个build.gradle文件,比如我设置的utils.gradle,settings.gradle。
如何在多个脚本中设置属性呢?
Gradle提供了一种名为 extra property 的方法。
extra property 是额外属性的意思,在第一次定义该属性的时候需要通过ext前缀来标示它是一个额外的属性。
定义好之后,后面的存取就不需要ext前缀了。
ext属性支持Project和Gradle对象。即Project和Gradle对象都可以设置ext属性
自己动手
def versions = [:]
versions.lifecycle = "1.1.0"
versions.android_gradle_plugin="3.1.4"
def deps = [:]
def lifecycle = [:]
lifecycle.runtime = "android.arch.lifecycle:runtime:$versions.lifecycle"
lifecycle.extensions = "android.arch.lifecycle:extensions:$versions.lifecycle"
deps.lifecycle = lifecycle
deps.android_gradle_plugin = "com.android.tools.build:gradle:$versions.android_gradle_plugin"
ext.deps = deps
def build_versions = [:]
build_versions.min_sdk = 21
build_versions.target_sdk = 28
build_versions.build_tools = "27.0.3"
ext.build_versions = build_versions
那么依赖gradle_plugin就可以写成
classpath deps.android_gradle_plugin
sdk版本
minSdkVersion build_versions.min_sdk
targetSdkVersion build_versions.target_sdk
第三方依赖
implementation deps.lifecycle.runtime
implementation deps.lifecycle.extensions
运行,没有报错
网友评论