近期正在着手将一些项目中共用组件抽离到底层,封装为组件,发布到公司内网 Jrog 搭建的 Maven 库。并且想要尝试使用 Gradle Kotlin DSL 替代 Gradle Groovy 来构建项目,遇到了一些坑,特此记录分享以下。
开发环境
- Android Studio Giraffe | 2022.3.1 RC 1
- JDK 17
- AGP 8.0.2
Groovy 迁移到 Kotlin DSL
可以参考以下霍老师的这篇文章 快速迁移 Gradle 脚本至 KTS | Benny Huo
依赖 Jrog 插件
Gradle - Plugin: com.jfrog.artifactory
项目根目录
//依赖 jrog 插件
plugins {
//...省略其他插件
id("com.jfrog.artifactory") version "4.29.1"
}
Module 目录
plugins {
//...省略其他插件
id("com.jfrog.artifactory")
id("maven-publish")
}
修改输出的 AAR 文件名
android{
//...
defaultConfig {
minSdk = 21
version = 1
}
//以下 moduleCommonArtifactId 为自定义名称,version 为 defalut 的 version 值,当然怎么命名自己决定
libraryVariants.configureEach {
outputs.configureEach {
val output = this as BaseVariantOutputImpl
if (output.outputFileName.endsWith(".aar")) {
output.outputFileName = "${moduleCommonArtifactId}_${version}.aar"
}
}
}
//...
}
打包源码中的 Java 和 Kotlin 代码
//新增一个 androidSourcesJar 任务,将源码打包,最终打包一个 build/libs/XXX-sources.jar
tasks.register("androidSourcesJar", Jar::class.java) {
archiveClassifier.set("sources")
from(android.sourceSets["main"].java.srcDirs)
from((android.sourceSets["main"].kotlin as DefaultAndroidSourceDirectorySet).srcDirs)
}
将 jar 和 aar 一起发布到 Maven 库,以及传递本项目依赖的远程库
publishing {
publications {
//以下 "aar" 可以自定义
register("aar", MavenPublication::class.java) {
this.groupId = projectGroupId
this.artifactId = XXX
artifact(tasks["androidSourcesJar"])//打包 jar
artifact("$buildDir/outputs/aar/${XXX}_${version}.aar")//打包 aar
//生成 POM 文件,将添加的远程库传递给主工程
//大致思路时遍历添加该 Module 下通过 implementation 依赖的所有远程库
pom {
withXml {
val root = asNode()
val dependencies = (root["dependencies"] as groovy.util.NodeList).firstOrNull() as groovy.util.Node?
?: root.appendNode("dependencies")
configurations.configureEach {
this.dependencies.forEach {
if (this.name == "implementation" || this.name == "api") {
if (it.group?.isNotBlank() == true && (it.name.isNotBlank() || "unspecified" != it.name) && it.version?.isNotBlank() == true) {
val dependency = dependencies.appendNode("dependency")
dependency.appendNode("groupId", it.group)
dependency.appendNode("artifactId", it.name)
dependency.appendNode("version", it.version)
dependency.appendNode("scope", "implementation")
}
}
}
}
}
}
}
}
}
最终生成 /build/publications/XXX/pom-default.xml 文件,形式如下
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<modelVersion>4.0.0</modelVersion>
<groupId>com.xxxxx.xxx</groupId>
<artifactId>ui</artifactId>
<version>0.2.1-SNAPSHOT</version>
<packaging>aar</packaging>
<dependencies>
<dependency>
<groupId>com.github.goweii</groupId>
<artifactId>Layer</artifactId>
<version>1.0.5</version>
<scope>implementation</scope>
</dependency>
<dependency>
<groupId>androidx.core</groupId>
<artifactId>core-ktx</artifactId>
<version>1.10.1</version>
<scope>implementation</scope>
</dependency>
<dependency>
<groupId>androidx.appcompat</groupId>
<artifactId>appcompat</artifactId>
<version>1.6.1</version>
<scope>implementation</scope>
</dependency>
<dependency>
<groupId>com.google.android.material</groupId>
<artifactId>material</artifactId>
<version>1.9.0</version>
<scope>implementation</scope>
</dependency>
</dependencies>
</project>
修改 Jrog 插件的 artifactoryPublish 任务
tasks.named<ArtifactoryTask>("artifactoryPublish") {
artifactory {
setContextUrl(mavenArtifactoryUrl)
clientConfig.publisher.repoKey = xxx
clientConfig.publisher.username = "xxx"//maven 库用户名
clientConfig.publisher.password = "xxx"//maven 库密码
}
dependsOn(tasks["assemble"])
//"aar" 同上
publications(publishing.publications["aar"])
}
Gradle Kotlin DSL 读取 gradle.properties 中定义的值
比如在 gradle.properties 有这么两个值
localDependency = false
isSnapshot = true
那么,在 build.gradle.kts 文件中
val localDependency : String by project
val isSnapshot: String by project
通过自带的委托属性获取同名值,必须同名,且只能 String 类型,没有摸索到如何转为 Boolean 值,有知道的朋友可以告知。
注: 有同学提醒可以用 .toBoolean() 来转为布尔类型