gradle 查看依赖类库版本_使用Gradle检测依赖库版本-程序员宅基地

技术标签: gradle 查看依赖类库版本  

背景

在Android开发过程中,我们会引入很多的第三方库,这些第三方库又会引入别的库,就可能出现版本不一致的问题。

Gradle在处理这种依赖冲突的策略是以版本最高(或指定)的版本打进APK包中。

这些问题在编译时无法发现,所以可能在运行时出现ClassNotFound,MethodNotFound之类的异常。

例如:

一个APK项目中,引入了ImageLoader和Album两个第三方库,这两个库引用的Glide版本不一致,

在最后打包的过程中,低版本会被忽略。

如果依赖库的高版本不支持低版本的API的话,那么就会出现运行时异常了,这个错误只能在运行时出现。

Album模块因为编译时api和运行时api不同导致出现了这个NoSuchMethodError错误。

为此我们打算开发一个插件,解决上面的问题,如果在编译时发现有版本不一致,就会停止编译,提示开发者解决。

使用Gradle Plugin实现检测功能

首先我们自定义一个Gradle Plugin,然后我们将这个Plugin的task hook到编译的task中,这里我们选择的hook点是preBuild,大家可以看下,这个是最先运行的task,在这个位置检测依赖比较合适。

target.tasks.findByName('preBuild').dependsOn(target.tasks.findByName(PLUGIN_NAME))

从Project中可以获取Configuration,我们遍历这些Configuration对象,找到名字是releaseRuntimeClassPath的,这个代表编译模式是release情况下,运行时的所有ClassPath依赖。

找到这个Configuration后,我们在从这个Configuration中获取所有的dependencies

conf.incoming.resolutionResult.root.dependencies,dependencies可能会依赖一些子Module,这些子Module仍然会依赖别的模块,所以此处需要递归进行处理。

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

// Plugin的apply方法

@Override

voidapply(Projecttarget){

// 创建一个Ext数据

target.extensions.create(EXT_NAME,DependenceChecker)

println("=============apply===============")

DependenceCheckerext=target.extensions.DependenceChecker

// 向Project中追加一个Task

target.task(PLUGIN_NAME)<

MapdepMap=newHashMap()

StringcheckMode="${ext.variant}runtimeclasspath"

printlntarget.configurations

target.configurations.each{Configurationconf->

//  考虑多个Flavor的情况

if(conf.name.toLowerCase().contains(checkMode)){

// 获取所有依赖信息

conf.incoming.resolutionResult.root.dependencies.each{dr->

resolveDependencies(depMap,dr)

}

printDepInfo(depMap)

reportDepInfo(depMap,ext.abortBuild)

}

}

}

target.tasks.findByName('preBuild').dependsOn(target.tasks.findByName(PLUGIN_NAME))

}

递归处理所有的依赖

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

staticdefresolveDependencies(Map>map,DependencyResultdr){

defdepName=dr.requested.displayName

if(dr!=null&&!depName.contains("project")){

String[]depSplit=depName.split(":")

if(depSplit.length>2){

defpackageName=depSplit[0]+depSplit[1]

deflist=map.get(packageName)

if(list==null){

list=newHashSet()

map.put(packageName,list)

}

list.add(depName)

}

}

// 如果这个dependences的类型是ResolvedDependencyResult,那么它内部还有依赖关系

if(drinstanceofResolvedDependencyResult){

dr.selected.dependencies.each{subDr->

resolveDependencies(map,subDr)

}

}

}

核心检测逻辑是我们如果判断同一个ClassPath对象是否有两个版本,如果存在两个版本,那么证明我们的项目中存在依赖冲突,运行时存在风险。所以终止编译,抛出个异常告诉开发者。

1

2

3

4

5

6

7

8

9

10

11

staticdefreportDepInfo(MapdepMap,booleanabortBuild){

depMap.each{k,v->

if(v.size()>1){

if(abortBuild){

thrownewRuntimeException("${k} has duplicate dependences, please resolve it...\n\n${v}")

}

}

}

}

插件使用

我已经此插件开源,大家可以从此处下载,下面介绍下这个插件的使用方法。

####1. 添加maven仓库,后续会传到jCenter,不用单独配置了。

1

2

3

4

5

6

repositories{

maven{

url'https://yangtianrui.bintray.com/maven'

}

}

####2. 项目根目录中的build.gradle中添加依赖

1

2

3

4

dependencies{

classpath'com.yangtianrui.tools.rdc:RuntimeDependenceChecker:1.0.0'

}

####3. 在APP模块的build.gradle中引入plugin

1

2

applyplugin:'DependenceChecker'

####4. 添加配置

variant表示需要检测的构建类型,这里以release为例。

abortBuild表示如果出现依赖冲突时,停止编译。

1

2

3

4

5

DependenceChecker{

variant='release'

abortBuild=true

}

例如:

这里在主项目中的Glide版本和其他模块的Glide版本冲突,如果配置了abortBuild那么就会停止编译,我们需要处理此冲突,否则运行时可能出现异常。

依赖冲突的处理

####1. 使用./gradlew :app:dependencies查看出来冲突的版本。

####2. 将冲突库的其中一个或多个升级或降级,将依赖库版本对齐。

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

智能推荐

Python AES_ECB_PKCS5加密代码_python rsa pkcs5-程序员宅基地

文章浏览阅读2.8k次。#!/usr/bin/env python# coding=utf-8# Created by slowchen on 2018/1/10 13:48.import base64import refrom Crypto.Cipher import AESclass AESECB: def __init__(self, key): self.key =_python rsa pkcs5

数据结构课设:中国计算机设计大赛赛事统计_编程大赛统计数据-程序员宅基地

文章浏览阅读328次。本次课程设计要求协助中国大学生计算机设计大赛江苏省组委会,设计一款赛事管理系统,实现赛务相关的数据管理及信息服务该系统能够为省级赛事管理解决以下问题:(1)能够管理各参赛队的基本信息(包含参赛队编号,参赛作品名称,参赛学校,赛事类别,参赛者,指导老师),赛事类别共11项(参见大赛官网包括增加、删除、修改参赛队伍的信息。(2)从team.txt中读取参赛队伍的基本信息,实现基于二叉排序树的查找。_编程大赛统计数据

cocos2d-js:cc.LoaderScene.preload_cocos2d js preload 替换-程序员宅基地

文章浏览阅读3.5k次。cc.LoaderScene()最基本的加载一个场景cc.LoaderScene.preload(res,function,tag)是可以在加载一个场景的过程中,返回一个加载资源进度的进度条,在完成资源加载后,回调function函数。_cocos2d js preload 替换

NIFI源码Maven打包遇到问题记录_nifi1.25.0 idea-程序员宅基地

文章浏览阅读764次,点赞12次,收藏15次。2.文件swagger-ui-3.12.0.tar.gz解压后放在D:\DataCenter\code\nifi-rel-nifi-1.25.0\nifi-registry\nifi-registry-core\nifi-registry-web-api\target下,需解压,target文件没有时,自己创建;这个C:\Users\z00050365\AppData\Local\Temp目录下,下载了一个commons-daemon-1.2.1-bin-windows.zip包,去网上没下下来。_nifi1.25.0 idea

深度学习经典网络解析图像分类篇(六):GoogLeNet_辅助分类器-程序员宅基地

文章浏览阅读3.6k次,点赞8次,收藏21次。深度学习经典网络解析(五):VGG1.背景介绍2.GoogLeNet创新点3.串联结构(如VGG)存在的问题4.GoogLeNet4.1 网络架构4.1.1 INPUT层4.1.2 Conv 1×14.1.2 Conv 3×34.1.3 Inception 3a层4.1.4 Inception 3b层4.1 Inception模块4.2 取消全连接层4.3 辅助分类器5. 思考5.1 平均池化向量化与直接展开向量化有什么区别?5.2 利用1x1卷积进行压缩会损失信息吗?6.GoogLeNet相关论文及下载地_辅助分类器

Acwing-基础算法课笔记之搜索与图论(bellman-ford算法)-程序员宅基地

文章浏览阅读1k次,点赞24次,收藏24次。bellman-ford算法适用于负权边的图,求 1 到 n 的最多经过k条边的最短距离。123dist0∞\infty∞∞\infty∞⇓\Downarrow⇓123dist01∞\infty∞⇓\Downarrow⇓123dist012此过程中出现了串联的结果,所以是错误的,此时需要进行备份操作。i < k;i++){//backup存的是上一次迭代的结果j < m;j++){

随便推点

玩转KVM:怎么追查KVM故障_original error from libvirt: cannot access storage-程序员宅基地

文章浏览阅读375次。上篇聊了下KVM的安全知识:TLS?有什么用?我们这次聊聊怎么追查KVM故障,以及KVM的故障应该怎么处理。1、libvirt的运行日志在运行libvirt的时候,我们需要获得lbivirt的运行信息,所以我们需要找到他的日志文件。一般情况下,它是在/var/log/libvirt/libvirtd.log路径下。如果在这个目录下没有发现这个的日志文件,那么就要配置一些libvit的参..._original error from libvirt: cannot access storage file

24西安电子科技大学833 834考研经验(涵盖各个阶段复习计划)_西电833_西安电子科技大学考研编号-程序员宅基地

文章浏览阅读718次,点赞23次,收藏9次。还有兄弟不知道网络安全面试可以提前刷题吗?费时一周整理的160+网络安全面试题,金九银十,做网络安全面试里的显眼包!王岚嵚工程师面试题(附答案),只能帮兄弟们到这儿了!如果你能答对70%,找一个安全工作,问题不大。对于有1-3年工作经验,想要跳槽的朋友来说,也是很好的温习资料!【完整版领取方式在文末!!_西安电子科技大学考研编号

八年级上学期计算机教学计划,八年级信息技术教学计划-程序员宅基地

文章浏览阅读130次。一、学生基本情况及指导思想本计划针对八年级四个班的全体学生,根据学校工作计划和中学信息技术《课程指导意见》以及学生的具体情况,明确中学信息技术课程的任务:培养学生对信息技术的兴趣和意识,让学生了解或掌握信息技术基本知识和技能,使学生具有获取信息、传输信息、处理信息和应用信息技术手段的能力,形成良好的信息技术素养,为他们适应信息社会的学习、工作和生活打下必要的基础。通过上年的学习,学生对办公软件例..._八年级上册计算机课程内容

蓝桥试题集-基础练习-BASIC-18~21-矩阵面积交-完美的代价-数的读法-Sine之舞_basic-21-程序员宅基地

文章浏览阅读144次。BASIC-18 矩阵面积交资源限制时间限制:1.0s 内存限制:512.0MB问题描述平面上有两个矩形,它们的边平行于直角坐标系的X轴或Y轴。对于每个矩形,我们给出它的一对相对顶点的坐标,请你编程算出两个矩形的交的面积。输入格式输入仅包含两行,每行描述一个矩形。 在每行中,给出矩形的一对相对顶点的坐标,每个点的坐标都用两个绝对值不超过10^7的实数表示。输出格式输出仅包含一个实数,为交的面积,保留到小数后两位。样例输入1 1 3 32 2 4 4样例输出_basic-21

ExtJS4.2学习(15)树形表格-程序员宅基地

文章浏览阅读203次。本节为ExtJS表格学习的最后一节,学完我将学习表单与输入控件的内容。树形表格(TreeGrid)同时具备树形的分级结构和表格的丰富内容。先引入扩展组件,老规矩://引入扩展组件 Ext.Loader.setConfig({enabled: true}); Ext.Loader.setPath('Ext.ux', '../Ext..._extjs treegrid

opencv3 视频稳像_stabframe未响应-程序员宅基地

文章浏览阅读4.1k次,点赞6次,收藏24次。OpneCV3.x中提供了专门应用于视频稳像技术的模块,该模块包含一系列用于全局运动图像估计的函数和类。结构体videostab::RansacParams实现了RANSAC算法,这个算法用来实现连续帧间的运动估计。videostab::MotionEstimatorBase是基类中所有全局运动估计方法,videostab::MotionEstimatorRansacL2描述了一个健壮的RANSA_stabframe未响应

推荐文章

热门文章

相关标签