Android项目分仓后引用aar或引用源码的切换

假设你是个大牛,你要开发一个库(niubi.aar)给大家用。你要不断地切换引用aar或引用源码,这种重复劳动,一定要越简单越好。

上一篇博客(发布jar和aar到github)演示了把libModule打包成aar并发布到maven仓库(github做为仓库)。

实际开发中,我们的项目已经分仓,libModule是放在独立的git仓库中。因为还要经常修改libModule中的代码,所以每次修改后再重新发布aar,然后在app项目中重新引用。反反复复会浪费不少时间。所以,我想在开发中引用源码,开发完成后引用aar自测,最后发布aar。

今天,我们就讨论一下怎么高效地完成这个过程。


要实现这个需求,要考虑以下问题:

  1. 拉取libModule的源码

  2. settings.gradle怎么写,如果引用源码,肯定要在这里配置,但是切换成引用aar后,还要删掉相应的配置。

  3. 在app中怎么引用libModule? 很容易想到:(useSrc定义在project 的 build.gradle 的 ext中,最终,我们会优化一下这里:) )

    1
    2
    3
    4
    5
    if (rootProject.useSrc) {
    implementation project(':droidLib')
    } else {
    implementation 'com.dwvip.demolib:droidLib:1.0'
    }
  4. 如果能对普通开发人员隐藏,对sdk开发人员开放,那就最好了。

拉取libModule的源码:

写shell或bat脚本?要维护两套脚本,不太明智。做android开发,我们为什么不用gradle脚本呢?在网上一搜,还真有现在的git操作的插件grgit。然后,我简单写了拉取代码的task cloneLibSrc(命令行中,在工程目录下执行./gradlew cloneLibSrc即可。Android Studio中鼠标操作也一样,在gradle Tasks(root) —> other —> cloneLibSrc)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
import org.ajoberstar.grgit.Grgit

task cloneLibSrc {
doLast {
doClone('demoLib', 'git@github.com:andych008/demoLib.git', 'master')
}
}

//如果判断libSrc这个文件夹不存在,就clone,否则pull。这里简单处理就行,不需要浪费时间
void doClone(String dirName, String remote, String branch) {
File dir = new File('libSrc/'+dirName)
if(!dir.exists()) {
def grgit = Grgit.clone(dir: dir, uri: remote, refToCheckout: branch)
}
def grgit = Grgit.open(dir: dir)
grgit.checkout(branch: branch)
grgit.pull(rebase: false)
}

settings.gradle怎么写:

本来想在定义rootProject.ext.useSrc = [true|false],但是在settings.gradle中不能这样操作。不知道为什么。最后,换个思路也能实现。如下:

1
2
3
4
5
6
7
8
include ':app'
//是否引用源码的开关
rootProject.name+="-Debug"

if (rootProject.name.indexOf("Debug") > 0) {
include ':droidLib'
project(':droidLib').projectDir = new File(settingsDir, './libSrc/demoLib/droidLib')
}

在app中怎么引用libModule?

如果在项目中,太多的if (rootProject.useSrc)判断,是不是很恶心?,所以,我们这样来写:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
//project build.gradle
ext{
useSrc = (rootProject.name.indexOf("Debug") > 0)

println("rootProject.ext.useSrc = " + rootProject.ext.useSrc)
if (useSrc) {
dependencies = [
"droidLib" : project(':droidLib')
]
} else {
dependencies = [
"droidLib" : 'com.dwvip.demolib:droidLib:1.0'
]
}
}
1
2
//app module
implementation rootProject.ext.dependencies["droidLib"]

这样,就可以在settings.gradle里控制开关,project 的build.gradle统一管理依赖。如果依赖项比较多,而且,aar还依赖更底层的aar,你就知道这样写的必要性了。

没有demo说代码都是耍流氓

以上代码及操作步骤都在这个demo里。https://github.com/andych008/demoMultiRepo