使用 Gradle Kotlin DSL 将 Android

近期正在着手将一些项目中共用组件抽离到底层,封装为组件,发布到公司内网 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") {
                                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 值,有知道的朋友可以告知。

全部评论

相关推荐

MGlory:我当初有一个老师告诉我简历要写的简单,最好只一面,项目可以写核心的,进面了自然会问你的
点赞 评论 收藏
分享
小厂面经,也是我的处女面(30min)1.自我介绍2.spring&nbsp;boot的自动装配原理(好多类和接口的单词都忘了全称是啥了,就说了记得的单词,流程应该说对了吧)3.有用过redis吗?主要是用在实现什么功能(说了技术派用redis的zset来实现排行榜)5.有了解过Redisson吗?讲一下对于分布式锁的了解以及在什么场景下应用(说了秒杀场景)6.对mysql有了解吗?包括它的索引优化和创建(把想起来的全说了)7.了解设计模式吗?比如单例模式,为什么要使用单例模式,它的优点是什么(昨天刚看的设计模式)8.工厂模式有了解吗?主要的使用场景是?(也是昨天刚看的)9.场景题:有7个服务器,需要在早上十点定时的向数据库中的用户表中的用户发短信,如果做到发送的消息不重复,且如果发送失败了需要知道是到哪个用户失败了,这样下次就直接从这个用户开始(我答了用spring&nbsp;task来实现定时,用分布式锁来保证只有一份服务器可以发送消息,用消息队列来存储消息,然后用消息确认机制来保证错误信息的记录,以及在数据库或者业务层面完成消息消费的幂等性)10.场景题:如果在系统启动的时间就将数据库的所有用户相关的信息都读到一个hashmap中(这个没啥思路,没答好)27届的投了一个星期终于有一个面试了,大部分公司都只招26的
inari233:已oc,拒了
查看9道真题和解析
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客企业服务