本文基于Android Studio,借助Gradle插件 —— Maven Publish,实现在构建完安卓或Java库之后,自动将之部署至maven仓库,使其成为一个公共模块,供其他项目引用。
首先了解一下其他多模块开发方法。
- 第一种:在setting.gradle中定义子模块然后
api Project(':...'))
,直接引用 。 - 第二种,部署至远程服务器,如 jitpack.io(傻瓜式操作,还支持gitee)
第一种方法适合小库,优点是改动后可一键构建运行,缺点是不适合维护较大的公共库,易于拖慢整体编译速度并造成分支混乱。
第二种方法的优点是可以给别人用,但是远程构建比较缓慢,不是增量编译,不适合开发时使用。
两种方法各有优缺,于是我找到了第三种几乎两全其美的方案:上传库至本地maven缓存。使用gradle的脚本或maven的pom.xml时,依赖项一般会下载到c:/user/admin/.m2/,我们在开发的过程中可以先将库上传到这个地方,对外发布时再上传至远程仓库。
具体做法很简单,在 Library 的 build.gradle 中写上一段话即可:
apply plugin: 'maven-publish'
publishing {
publications {
maven(MavenPublication) {
from components.java
groupId "org.appxmod.metaline"
artifactId "Metaline"
version "1.0.0"
}
}
}
build.finalizedBy publishToMavenLocal
分段解读一下,第一段引入插件maven-publish
,第二段publishing {...
定义模块 的相关属性。第二段配置成功后,插件会为我们生成四个gradle任务(task),可以在Android Studio的Gradle面板(默认停靠在右侧顶部)中找到并双击运行。其中一个任务的名字是 publishToMavenLocal,也就是上传编译好的库至 mavenLocal 了!
第二段里面再分解一下。首先from components.java
是固定写法,对于纯Java库有效,上传jar文件,并根据其依赖项生成pom文件。用于安卓库可能会报错,还说“Java不是个东西”:
Could not get unknown property java for SoftwareComponentInternal
只好舍弃from components.java
,强制指定构建出来的aar文件,比如:artifact "build\\outputs\\aar\\glide-debug.aar"
此时上传的是aar文件,一旁的pom文件中却没有任何依赖库,可能需要自行引用。不知标准做法是不是也这样,Maven Publish 的官方文档太长没有看,希望英语好的同学可以取经一下,然后为我等解惑~
其次groupId是包名,artifactId 是库名,再加上 version 版本号就差不多啦。其他项目引用的时候,先在最外层的build.grale中添加mavenLocal():
buildscript {
repositories {
mavenLocal()
……
}
allprojects {
repositories {
mavenLocal()
……
}
这样就可以像引用远程依赖一样引用本地库了!写法是 api groupId:artifactId:version
。
以我的元线模块为例,引用起来是这个样子的:
Gradle
buidl.gralde,dependency:
compileOnly libs_metaline
annotationProcessor libs_metaline
gradle.properties:
libs_metaline=org.appxmod.metaline:Metaline:1.0.0
Maven
<dependency>
<groupId>org.appxmod.metaline</groupId>
<artifactId>Metaline</artifactId>
<version>1.0.0</version>
<scope>provided</scope>
</dependency>
(因为是编译期的注解处理器,所以用compileOnly 、annotationProcessor 、provided方式引入)
第三段build.finalizedBy publishToMavenLocal
,含义是在build任务运行完成后,接着运行publishToMavenLocal任务,也就是编译后自动部署。需要注意的是,编译失败可能也会上传。
破案了,安卓库需要用afterEvaluate
包起来:
afterEvaluate {
publishing {
publications {
mavenAll(MavenPublication) {
from components.all
groupId "org.appxmod.android"
artifactId "RecyclerView"
version "1.0.0"
}
}
}
}