技术经验谈 技术经验谈
首页
  • 最佳实践

    • 抓包
    • 数据库操作
  • ui

    • 《JavaScript教程》
    • 《JavaScript高级程序设计》
    • 《ES6 教程》
    • 《Vue》
    • 《React》
    • 《TypeScript 从零实现 axios》
    • 《Git》
    • TypeScript
    • JS设计模式总结
  • 总纲
  • 整体开发框架
  • 技术文档
  • GitHub技巧
  • Nodejs
  • 博客搭建
  • 学习
  • 面试
  • 心情杂货
  • 实用技巧
  • 友情链接
关于
收藏
  • 分类
  • 标签
  • 归档
GitHub (opens new window)

hss01248

一号线程序员
首页
  • 最佳实践

    • 抓包
    • 数据库操作
  • ui

    • 《JavaScript教程》
    • 《JavaScript高级程序设计》
    • 《ES6 教程》
    • 《Vue》
    • 《React》
    • 《TypeScript 从零实现 axios》
    • 《Git》
    • TypeScript
    • JS设计模式总结
  • 总纲
  • 整体开发框架
  • 技术文档
  • GitHub技巧
  • Nodejs
  • 博客搭建
  • 学习
  • 面试
  • 心情杂货
  • 实用技巧
  • 友情链接
关于
收藏
  • 分类
  • 标签
  • 归档
GitHub (opens new window)
  • 编译和自动化

    • gradle基础
    • gradle-task
    • appbundle打包的自动化
    • cmake vs gradle
    • cmake入门
    • gradle依赖管理
      • 仓库
      • 坐标
      • 文件结构
        • 远程仓库
        • 私服-nexus
        • 任意公开目录
        • 本地仓库
        • 本地maven仓库: mavenLocal()
        • gradle在本地的缓存文件夹
      • 统一管理依赖版本
      • 全局锁定依赖版本
      • 单个
      • 全局
      • 命令行方式:
      • gradle脚本方式:
      • 两个概念:
        • 输出依赖树
        • 输出依赖列表
      • 检查依赖列表里哪些版本有新版本,最新版本是多少,并输出报告
    • gradle加速之拉取依赖的加速
    • gradle远程脚本
    • maven
    • 多module时自动发布所有lib
    • 将react native打包成一个aar
  • 异常上报和监测

  • SDK封装方法论
  • 结构化文档一键转代码的实践-埋点-翻译-java api注释
  • 防御式编程例子1-颜色解析工具的处理
  • 工程方法
  • 编译和自动化
hss01248
2022-05-06
目录

gradle依赖管理

# gradle依赖管理

# 官方工具

./gradlew clean app:assembleDebug --scan
1

它会自动发送到scans.gradle.com网址下 (opens new window)

有编译耗时统计

image-20220506145116311

image-20220506145154868

且有依赖,仓库,插件列表分析:

image-20220506145245842

# 历史演进

  • 1 最原始的: 拷代码,自己编译. 目前c和c++的依赖管理就是这个水平,没有统一的包管理工具

  • 2 帮你编译好,你去官网下载jar包,放到libs目录下

  • 3 所有jar到放到一个统一的地方,按统一的规则来组织,上传,下载.

说jar包只是例子,aar,js,python库,都是这个范畴

衍生出两个核心概念

# 核心概念

# 仓库

用于存储,管理jar包等.

又有中央仓库,镜像仓库,私有仓库(私服),本地仓库之分. 也是多级缓存的体现

image-20220102193901183

一个项目里会用到哪些仓库?

Google : https://dl.google.com/dl/android/maven2/
BintrayJCenter : https://jcenter.bintray.com/
MavenRepo : https://repo.maven.apache.org/maven2/
maven : https://git.xxxx.com:8888/repository/maven-snapshots/
maven2 : https://git.xxxx.com:8888/repository/maven-releases/
maven3 : https://git.xxxx.com:8888/repository/maven-public/
MavenLocal : file:/Users/hss/.m2/repository/
maven4 : https://jitpack.io
Google2 : https://dl.google.com/dl/android/maven2/
BintrayJCenter2 : https://jcenter.bintray.com/
MavenRepo2 : https://repo.maven.apache.org/maven2/
maven5 : https://maven.fabric.io/public
maven6 : https://jitpack.io
Google3 : https://dl.google.com/dl/android/maven2/
BintrayJCenter3 : https://jcenter.bintray.com/
MavenRepo3 : https://repo.maven.apache.org/maven2/
maven7 : https://jitpack.io
MavenRepo4 : https://repo.maven.apache.org/maven2/
BintrayJCenter4 : https://jcenter.bintray.com/
Google4 : https://dl.google.com/dl/android/maven2/
flatDir : null
MavenLocal2 : file:/Users/hss/.m2/repository/
maven8 : https://maven.google.com
maven9 : https://jitpack.io
maven10 : https://maven.fabric.io/public
maven11 : https://oss.sonatype.org/content/repositories/snapshots/
maven12 : http://nexus2.tingyun.com/nexus/content/repositories/snapshots/
maven13 : https://git.xxxx.com:8888/repository/maven-snapshots/
maven14 : https://git.xxxx.com:8888/repository/maven-releases/
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

# 坐标

image-20220102194837396

com.google.zxing:core:2.3.0

com.google.zxing--> groudId

core --> artifactId

2.3.0 -->version

URL 统一资源定位符

https://repo1.maven.org/maven2/com/google/zxing/core/2.3.0/

maven仓库搜索:

https://mvnrepository.com/

# 文件结构

# 远程仓库

groupId/artifactId路径下,metadata.xml存放了版本列表信息

image-20220102200436373

image-20220102200524312

具体的版本号路径下,存储了这个版本发布的包

至少有pom.xml, 以及打包产物比如jar,aar,javadoc等

image-20220102200759009

pom.xml

image-20220102201409237

# 私服-nexus

开源,自行搭建.

# 任意公开目录

不想申请maven central账号,不想搭nexus, 不想用jitpack发,怎么搞?

直接在任意公开目录,构建符合maven的文件结构,比如:

示例:

https://github.com/link-u/AndroidGlideAvifDecoder

repositories {
    ...
    maven { url 'https://github.com/link-u/AndroidGlideAvifDecoder/raw/master/repository' }
    ...
}

...

implementation 'jp.co.link_u.library.glideavif:glideavif:0.8.1'
1
2
3
4
5
6
7
8
9

# 本地仓库

# 本地maven仓库: mavenLocal()

或者增加其他文件夹:

maven { url "${System.env.HOME}/creativesdk-repo/release" }
maven { url "../react-navive/android/gist" }
1
2

没有metadata.xml

image-20220102201013895

image-20220102201118920

# gradle在本地的缓存文件夹

存放的是aar解压后的文件. 而不是像mavenLocal一样原原本本的jar包/aar包

image-20220102202229073

image-20220102202306086

文件名是那个依赖包的md5,无规律. 毕竟只是个缓存

image-20220102202455855

纯jar包的话,就没有解压缩成文件夹

image-20220102202742047

image-20220102195125120

# 依赖版本

# 统一管理依赖版本

maven有dependencymanagement, 其子module不用指定版本号

gradle: 使用rootProject里ext定义额外属性或者使用Version Catalog (opens new window)这个新特性

image-20220102205243842

image-20220102205256829

# 全局锁定依赖版本

project.configurations {
    all {
        resolutionStrategy {
            force "com.google.android.material:material:1.2.1"
        }
    }
}
1
2
3
4
5
6
7

# 排除依赖

# 单个

api ('commons-httpclient:commons-httpclient:3.1'){
        exclude group:'commons-codec' //排除该group的依赖
        // exclude group:'commons-codec',module:'commons-codec'
        // group是必选项,module可选
    }
1
2
3
4
5

也可以替换传递的依赖:

compile group:'a',name:'a',version:'l.0' {
    dependencies 'b:b:1.1'
}
1
2
3

# 全局

project.configurations {
    all*.exclude group: 'com.github.yalantis'
    all*.exclude group: 'com.google.guava', module: 'listenablefuture'
}
1
2
3
4

# 强制刷新依赖

snapshot依赖默认本地缓存24h,所以发布新的sanpshot时,一般都需要强刷.

参考:Gradle强制刷新单模块依赖 (opens new window)

有几种方式:

# 命令行方式:

会强制忽略所有模块缓存.不仅仅包括snapshot,还包括正式版本

作用于当次. 此次构建速度会减慢.

Windows:    
gradlew build --refresh-dependencies 


Mac:
./gradlew build --refresh-dependencies  
1
2
3
4
5
6

# gradle脚本方式:

project.configurations.all {
    resolutionStrategy.cacheDynamicVersionsFor 10, 'minutes'
    // resolutionStrategy.cacheChangingModulesFor 4, 'hours'
    resolutionStrategy.cacheChangingModulesFor 0, 'seconds'
}

1
2
3
4
5
6

# 两个概念:

DynamicVersions是指:

implementation 'com.example:library:1.+'
1

ChangingModules是指snapshot:

implementation 'org.example:library:1.0.0-SNAPSHOT'
1

对于nexus来说,一般的管理方式是:

snapshot可以一直发

image-20210425150827718

而release也可以一直发同一个版本,后发的会覆盖前一个发的.

一般推荐关闭正式版本的覆盖功能,不允许覆盖,只允许升级.

如果非要覆盖,那么gradle此处可以相应配置:

即声明对应的正式版本也是可变化的,那么就可以同snapshot一样刷新

implementation('org.example:library:1.0.0'){
        changing = true
    }
1
2
3

# 查看项目所有依赖:

./gradlew :app:dependencies --configuration releaseRuntimeClasspath > old.txt
1

image-20210524194717499

几个release版本之间依赖的差异,可以使用:

https://github.com/JakeWharton/dependency-tree-diff

配合gradle脚本,输出报告

# 输出依赖树

比如:

#!/bin/bash
set -e
echo "生成依赖树到文件dependencies.txt中,每次建release时,以及发版后merge到master之前运行此脚本一次,便于通过git追踪各版本依赖的变化"
./gradlew :app:dependencies --configuration releaseRuntimeClasspath > dependencies.txt
1
2
3
4

image-20210524200502542

# 输出依赖列表

核心api

runtimeConfiguration.resolvedConfiguration.lenientConfiguration.allModuleDependencies.forEach { dependency: ResolvedDependency ->
                dependency.moduleArtifacts.forEach { artifact: ResolvedArtifact ->
                    val newDep = MavenCoordinates(
                        dependency.moduleGroup, dependency.moduleName,
                        dependency.moduleVersion, artifact.type, artifact.classifier
                    )
                }
}
1
2
3
4
5
6
7
8

定义task,挂载到工程,输出到文件:

https://github.com/hss01248/flipperUtil/blob/master/deps/depsParser.gradle

可以用于:

  • 检测snapshot版本
  • 检测过旧的版本
  • 检查实际依赖版本

# 检查依赖列表里哪些版本有新版本,最新版本是多少,并输出报告

仓库+坐标,访问其maven-metadata.xml,解析,并与项目中的对比即可.

开启gradle的并发功能, 多线程并发请求加速, 主线程循环等待.

depsLastestChecker.gradle (opens new window)

image-20220102204000938

# 脚本里动态增删依赖

https://juejin.cn/post/6971807367184777246

https://github.com/hss01248/MyDataStore/blob/script/test.gradle

# 一键发布工程中所有lib到nexus

maven本身就支持,而gradle需要自己写脚本实现

思路

解析release依赖树

从叶子开始发布(深度优先)

然后再发布上一层. 发布此层时发现为project依赖,则指定预先设置的groupId,artifactId,以及版本号再发布.

脚本挂载到gradle的listener上,与工程完全解耦,仅远程脚本交互.

image-20220102204233456

image-20220102204410685

通用脚本使用如下:

Android代码库一键发布到nexus/本地maven (opens new window)

# 参考

Gradle依赖管理 (opens new window)

第五十章. 依赖管理 (opens new window)

# 非常好的博客

gradle官方文档-ResolutionStrategy dsl (opens new window)

project.afterEvaluate { 
    project.gradle.taskGraph.whenReady { 
        println("=======> print allTasks")
        println(project.gradle.taskGraph.allTasks) 
    } 
}

作者:弄码哥nomag
链接:https://juejin.cn/post/7043235150796161060
来源:稀土掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
1
2
3
4
5
6
7
8
9
10
11
编辑 (opens new window)
上次更新: 2022/08/25, 20:20:31
cmake入门
gradle加速之拉取依赖的加速

← cmake入门 gradle加速之拉取依赖的加速→

最近更新
01
截图后的自动压缩工具
12-27
02
图片视频文件根据exif批量重命名
12-27
03
chatgpt图片识别描述功能
02-20
更多文章>
Theme by Vdoing | Copyright © 2020-2025 | 粤ICP备20041795号
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式