引用其他project的module,根据参数自动配置依赖,repo管理多个 Project

引用其他project的module,根据参数自动配置依赖,repo管理多个 Project
前言在开发中遇到这样一个问题在工作的project以下简称Project A中用到了Fragmentation以下简称Project B 库的三个module这个库是我在维护平时更改库中的一些bug需要先使用一段时间再推到github并发布到jcenter 所以在我的工作项目中是直接使用本地的代码没有使用jcenter去引用它。这就遇到一个问题在Project A 中改完 Project B的三个module在等到发布的时候就需要手动把代码拷贝一份到Project B中。如何能让这个过程简单点呢有小伙伴想到了可以使用软连接这样改完工作项目中的这三个module就不再重复复制代码了。如果是多人协作开发就不行了。把Project B 这三个module 分别使用git管理整个工程项目使用repo 来管理这样不管是哪个project 都可以方便的使用这三个module但是这样对Project B 的改动较大。如果Project B 发布后Project A 想通过jcenter 来引用这三个module也不是很方便。这种方式改造完基本上就是现在江湖上组件化的结构于是在想使用repo 来管理不同的Projectrepo 本质是来管理多个git的所以是project还是model没有差别。这样可以来通过repo 来管理这个另外两个问题在Android studio中 一个project 如何使用另外一个project的module呢在本地没有 Project B如何让Project A 自动通过jcenter来引用使用repo 来管理项目repo 本质是来管理多个git的所以无论是project 还是module只要用git 来管理那么他们就可以被repo管理1、repo安装折腾过Android 源码的同学应该对这个很熟悉可以直接去配置default.xml然后按照自己的思路就可以创建bin 目录并加入到环境变量$mkdir~/bin $PATH~/bin:$PATH在bin 目录下下载repo 工具$curlhttps://storage.googleapis.com/git-repo-downloads/repo~/bin/repo $chmodax ~/bin/repo2、创建default.xmlrepo 是用python开发的工具 来管理不同项目的git需要通过一个配置文件default.xml来告诉他有哪些项目远程地址是什么本地路径是什么review 等等?xml version1.0 encodingUTF-8?manifest!-- --remotenamegithubfetchhttps://github.com/JantHsueh/remotenamealiyunfetchhttps://code.aliyun.com/cmoon/defaultremotealiyunrevisionmastersync-j4/projectnamecm-android.gitpathxw/projectnameFragmentation.gitpathFragmentationremotegithub//manifestremote远程仓库地址配置可以多个。name: 名字也用于子仓库的 git remote 名称.git/config 里的 remotealias: 别名可省略建议设为 origin 设置了那么子仓库的 git remote 即为此名方便不同的 name 下可以最终设置生成相同的 remote 名称fetch: 仓库地址前缀即 project 的仓库地址为: remote.fetch project.namepushurl: 一般可省略省略了则直接用 fetchreview: Gerrit code review 的地址如果没有用 Gerrit 则不需要配置也就不能用 repo upload 命令了revision: 使用此 remote 的默认分支default配置默认远程仓库地址remote :它的值 是上面remote 标签 配置的name 值表示远程仓库地址revision : 远程分支sync-j : 使用线程数projectname : 远程仓库的项目名配合remote标签的fetch值共同组成完整仓库地址remote.fetch project.namepath工程在本地的存储路径remote 它的值 是上面remote 标签 配置的name 值表示远程仓库地址。如果没有配置使用default中的配置更多参数配置查看官方文档repo Manifest Format3、repo 初始化 和代码下载# 初始化 repo default.xml 文件 会下载到 .repo/manifests/ 目录下repo init-uhttps://github.com/anlory/manifest# 根据配置下载代码reposync至此repo就把这两个project 管理起来了在项目中应该如何配置project直接的关系呢如何引用其他projectdefault.xml 在 .repo/manifests/ 目录下 为了在project 中 能方便的通过 default.xml 控制项目所以创建default.xml 软连接放在project中并加入到.gitignore 中在setting.gradle 中指定 module 的路径这样就可以指定到其他project 中的 moduleinclude:app,:mvvm//设置全局变量在setting.gralde 和 build.gradle 中设置环境变量是不一样的gradle.ext.localFragmentationfalse//在default.xml 中判断是否有对应的project如果有repo sync 后 本地就有对应的代码就配置使用本地工程代码def manifestnewXmlParser().parse(${rootProject.projectDir}/default.xml)manifest.project.each{it.attributes().each{k,v-// path 对应的值包含 Fragmentation 字段if(kpathv.contains(Fragmentation)){gradle.ext.localFragmentationtrue//指定Fragmentation工程的路径在本示例中两个工程的目录是同级的def path../Fragmentation include :Fragmentationproject(:Fragmentation).projectDirnewFile(path)include :fragmentationproject(:fragmentation).projectDirnewFile(path,fragmentation)include :fragmentation_coreproject(:fragmentation_core).projectDirnewFile(path,fragmentation_core)include :fragmentation_swipebackproject(:fragmentation_swipeback).projectDirnewFile(path,fragmentation_swipeback)}}}gradle.ext.xx 和rootProject.ext.xx的用法差不多只是变量存放的位置不同在build.gradle 中配置全局变量 使用 rootProject.ext.在setting.gradle中配置全局变量使用 gradle.ext更多全局变量的使用可参考这篇文章 gradle使用技巧之全局变量如何根据参数自动配置不同的依赖这个就很简单了根据上面设置的全局变量来判断dependencies{if(gradle.ext.localFragmentation){apiproject(:fragmentation)apiproject(:fragmentation_swipeback)}else{api me.xuexuan:fragmentationx:1.0.6 api me.xuexuan:fragmentationx-swipeback:1.0.6}}当然可以有更多的玩法下面代码是参考这里的需要引用哪个项目从gradle.properties的配置中获取。def moduleVersionsnewProperties()def moduleVersionsFilenewFile(${project.projectDir}/gradle.properties)moduleVersions.load(moduleVersionsFile.newDataInputStream())dependencies{def projectsmoduleVersions.stringPropertyNames()rootProject.subprojects.each{if(it.name!host){implementation it projects.remove(it.name)}}projects.each{//为了方便引用这里要求我们上传到 maven 的各模块的包遵循一定的规则groupid 需要保持一致// artifactid 最好是以子 module 的 project.name 来命名如果不是这样的规则就需要自己修改 gradle 脚本啦implementationme.ailurus.repo:${it}:${moduleVersions.getProperty(it)}}}结语在我看来上面这种方式算是project 之间的模块化由于 project 可以多module的原因很容易在多个project里 使用空 application 项目来打包apk请点赞、收藏感谢大家的支持欢迎评论区提问、吐槽参考使用 repo 组织 Android 工程Gradle Repo一个能管理多个Git仓库又能快速切换分支的Gradle插件用repo管理自己的仓库将数据从settings.gradle传递到build.gradleAndroid Studio在同一个窗口中打开多个Project【附效果图附源码】