Android 进阶——Android Studio 项目结构详细述及Gradle脚本语法dependencies节点和依赖管理完全解析(四)

版权声明:本文为博主原创文章,遵循 CC 4.0 BY 版权协议,转载请附上原文出处链接和本声明。
本文链接: https://blog.csdn.net/CrazyMo_/article/details/87895750

引言

前面一篇文章Android 进阶——Android Studio 项目结构详细述及Gradle脚本语法android剩余子节点配置完全解析(三)总结了下Android Studio中Gradle 脚本中最重要的android节点的配置相关知识,即主要是总结了针对android 插件自身进行配置的,这一篇是关于Gradle自身对于项目打包运行依赖的一些管理 ,Gradle系列文章链接如下:

一 、dependencies节点

1、基本配置

上面android节点内部是配置引入的Android插件的,而android节点之外则完全是配置指导Gradle编译的相关信息的,其中dependencies就是所谓的依赖库配置,在android中没有配置productFlavors节点时候功能语法和Project 根目录下的大同小异,而在配置了productFlavors之后,则可以针对不同的单个productFlavors 或者Build Type 进行配置不同的依赖库,同样的在选择对应的Build Variant时候会主动合并到主源集中。

dependencies {
    //引入文件树,这里会把libs目录下所有的jar包自动引入
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    implementation 'com.android.support:appcompat-v7:26.1.0'
    implementation 'com.android.support.constraint:constraint-layout:1.1.2'
    testImplementation 'junit:junit:4.12'
    androidTestImplementation 'com.android.support.test:runner:1.0.2'
    androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
    //引入指定jar包文件,这里传递是相对路径即相当于module下的build.gradle文件的路径,如以下写法则是引入与module下的build.gradle同路径下的jar包
    implementation files('crazymo.jar')
    //引入依赖库Module方式1
	 implementation project(':libcrazymo') 
	  implementation project(path:':libcrazymo') 
}

2、依赖管理及引入依赖

2.1、引入依赖命令

gradle3.0中compile依赖关系已被弃用,被implementation和api替代provided被compile only替代,apk被runtime only替代。

  • runtime only——只打包不参与编译,用于指定Gradle 不与应用的apk一起打包的依赖库,如果运行时无需依赖此依赖库,这将有助于apk大小的优化。

  • compile only——只编译不打包到apk

  • api——跟2.x版本的 compile完全相同

  • implementation——只能在内部使用此模块,比如我在一个library中使用implementation依赖了gson库且我的主项目依赖了library,那么主项目就无法访问gson库中的方法,这样的好处是编译速度会加快,推荐使用implementation的方式去依赖,如果你需要提供给外部访问,那么就使用api依赖即可。除了使用静态依赖的方式,还可以使用动态的形式进行依赖(实际项目中不太推荐),以下就是使用另一种形式进行依赖,虽然使用三句话都配置了相同的group和module的依赖,不过编译不会出错,因为Groovy会自动为你选择最新版本的并排除重复的。

注意:api 会自动传递依赖,而implementation不会自动传递依赖,举个例子在lib module中使用implementation依赖了第三方库GSON时,直接在app 主module无法使用,你需要改成api来依赖。
在这里插入图片描述
神奇的是即使同时使用上面的语句引入不同的动态版本,也不会发生依赖冲突,因为Groovy在处理依赖的时候,遇到同一group 和name的库时会自动使用最高版本的。

2.2、使用 gradlew :app:dependencies 查看app 所依赖库的关系。

其实这所谓的依赖关系就是各种对应.pom文件的图形展示。
在这里插入图片描述

3、依赖冲突解决

在编译过程中Gradle 除了会把脚本里配置的库自动引入之外还会把local.properties下的SDK和NDK 下的依赖库引入,作为一个本地代码库,这些是由android插件默认引入的
在这里插入图片描述
接下来以一个简单例子:

dependencies {
    implementation fileTree(include: ['*.jar'], dir: 'libs')
    androidTestImplementation('com.android.support.test.espresso:espresso-core:2.2.2', {
        exclude group: 'com.android.support', module: 'support-annotations'
    })
    implementation 'com.android.support:appcompat-v7:28.0.0'
    implementation 'com.android.support:recyclerview-v7:28.0.0'
    implementation 'com.github.hotchemi:permissionsdispatcher:2.3.0',{
        //把group为com.android.support ,module为support-v4的包排除依赖,如果不添加这段就会报以下的错误
        //exclude(group:'com.android.support',module:'support-v4')
    }
    annotationProcessor 'com.github.hotchemi:permissionsdispatcher-processor:2.3.0' //java8不能使用apt
}

在compileSdkVersion为28编译运行时会报如下的错误(从关键词可以初步判断是jar包冲突了):
在这里插入图片描述
接下来说明下解决依赖冲突的常见的步骤和流程:

3.1、首先通过 ./gradlew :app:dependencies 查看app 所依赖库的关系。

在这里插入图片描述

3.2、分析app 依赖库的关系

在这里插入图片描述

3.3、解决冲突

解决冲突的理论依据是因为Groovy给我们在DependencyHandler中重载了添加依赖的方法,其中有一个是允许传递闭包的(用于配置Dependency),在闭包里我们可以实现自己的逻辑去排除冲突

  • 使用ModuleDependency的 exclude传递group和module动态移除
 implementation 'com.github.hotchemi:permissionsdispatcher:2.3.0',{
        //把group为com.android.support ,module为support-v4的包排除依赖,如果不添加这段就会报以下的错误
        exclude(group:'com.android.support',module:'support-v4')
    }

则部分依赖关系为
在这里插入图片描述

  • 除了排除依赖,还可以指定不处理传递依赖 直接在闭包内配置 transitivie false,默认为true,这种十分不推荐因为有可能导致不能正常工作
    implementation 'com.facebook.fresco:fresco:0.14.0',{
        // 简单暴力 只依赖group为com.facebook.fresco name为fresco 版本为0.14.0的库,而其内部的内来哭不传递过来
        transitive false
    }

则编译之后库依赖关系变为

在这里插入图片描述

二 、configurations节点

配置项目的其他信息,可以支持很多操作,比如说配置编译的版本,自定义依赖分组的具体操作等等,甚至dependencies 内部用到的编译名称就是Groovy 默认先添加到configurations下的,当然你也可以像下面这样的添加自定义的分组,不过你得自己去实现功能。

在这里插入图片描述

三、SigningConfigs节点

在Android系统上系统是通过applicationId和签名来区分标识唯一apk的,为了安全性apk必须是签名才能运行在系统上的,默认情况下比如说在debug 变体下会去使用XXX/.android/debug.keystore进行签名,也可以给不同的ProductFlavor 去配置不同的签名
在这里插入图片描述
未完待续…

猜你喜欢

转载自blog.csdn.net/CrazyMo_/article/details/87895750