🌱 Branch: 13/jvm-only-modules
🔗 Repositório: github.com/rsicarelli/kotlin-gradle-android-platform
⬅️ Artigo Anterior: Parte 12: Otimizando tempo de compilação para bibliotecas Android
➡️ Próximo Artigo: Parte 14: Aderindo a funcionalidades experimentais do compilador do Kotlin
No último artigo, otimizamos a compilação dos módulos Android desativando diversas funcionalidades do Android Gradle Plugin (AGP).
Neste artigo, discutiremos a distinção entre módulos puro JVM (java-library
) e módulos Library Android (com.android.library
), além de expandir nossa plataforma para suportar essa funcionalidade.
O que são Módulos Puro JVM?
Módulos Puro JVM são aqueles que utilizam exclusivamente a JVM (Java Virtual Machine) para sua execução. Em outras palavras, não têm vínculo nem dependência direta com o Android.
Simplificando, são módulos puramente Java, isentos das especificidades e complexidades dos módulos Android.
Como resultado, as compilações são mais eficientes, já que esses módulos não passam pelas etapas de compilação do Android Gradle Plugin (AGP).
Quando usar módulos puro JVM?
Lógica de negócios: Para códigos relacionados à lógica de negócios que não dependem diretamente do Android, como cálculos, validações ou manipulações de listas.
Bibliotecas Genéricas: Se você está desenvolvendo uma biblioteca que pode ser usada tanto em projetos Android quanto em projetos Kotlin/JVM puros.
Módulos 'core': Módulos relacionados a banco de dados, rede, logging, que podem ser construídos puramente em Kotlin/JVM.
Decorando nossa plataforma para receber módulos puro JVM
A proposta é adicionar um novo ponto de entrada chamado jvmLibrary()
e decorá-lo com a função applyJvmLibrary()
.
1 - Crie uma função fun Project.applyJvmLibrary()
no arquivo kotlin.kt
:
import org.gradle.api.JavaVersion
import org.gradle.api.Project
import org.gradle.api.plugins.JavaPluginExtension
import org.gradle.kotlin.dsl.configure
import org.gradle.kotlin.dsl.withType
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
internal fun Project.applyJvmLibrary() {
pluginManager.apply("java-library")
extensions.configure<JavaPluginExtension> {
sourceCompatibility = JavaVersion.VERSION_17
targetCompatibility = JavaVersion.VERSION_17
}
applyKotlinOptions()
}
internal fun Project.applyKotlinOptions() {
tasks.withType<KotlinCompile>().configureEach {
kotlinOptions {
jvmTarget = "17"
}
}
}
2 - Vamos manter o padrão da nossa plataforma e possibilitar que os módulos configurem a compilação individualmente. Isso irá possibilitar algumas novas customizações que iremos aplicar no próximo post:
Pra não deixar os Options
jogados por aí, vamos criar uma pasta build-logic/src/../options
e trazer AndroidOptions.kt
para lá.
Crie uma classe CompilationsOptions
e declare o conteúdo:
import org.gradle.api.JavaVersion
internal data class CompilationOptions(
val javaVersion: JavaVersion,
val jvmTarget: String,
val allWarningsAsErrors: Boolean,
)
class CompilationOptionsBuilder {
var javaVersion: JavaVersion = JavaVersion.VERSION_17
var jvmTarget: String = "17"
var allWarningsAsErrors: Boolean = false
internal fun build(): CompilationOptions = CompilationOptions(
javaVersion = javaVersion,
jvmTarget = jvmTarget,
allWarningsAsErrors = allWarningsAsErrors
)
}
3 - Vamos adaptar nossa função applyJvmLibrary()
pra receber um CompilationOptions
:
import com.rsicarelli.kplatform.options.CompilationOptions
import org.gradle.api.JavaVersion
import org.gradle.api.Project
import org.gradle.api.plugins.JavaPluginExtension
import org.gradle.kotlin.dsl.configure
import org.gradle.kotlin.dsl.withType
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
internal fun Project.applyJvmLibrary(compilationOptions: CompilationOptions) {
pluginManager.apply("java-library")
applyJavaCompatibility(compilationOptions.javaVersion)
applyKotlinOptions(compilationOptions)
}
internal fun Project.applyKotlinOptions(compilationOptions: CompilationOptions) {
tasks.withType<KotlinCompile>().configureEach {
kotlinOptions {
allWarningsAsErrors = compilationOptions.allWarningsAsErrors
jvmTarget = compilationOptions.jvmTarget
}
}
}
private fun Project.applyJavaCompatibility(javaVersion: JavaVersion) {
extensions.configure<JavaPluginExtension> {
sourceCompatibility = javaVersion
targetCompatibility = javaVersion
}
}
4 - Note que alteramos a assinatura da função applyKotlinOptions
que está sendo compartilhada entre nossas decorações android.kt
.
internal fun Project.applyAndroidApp(
androidAppOptions: AndroidAppOptions,
compilationOptions: CompilationOptions,
) {
applyAndroidCommon(
androidOptions = androidAppOptions,
compilationOptions = compilationOptions
)
..
}
internal fun Project.applyAndroidLibrary(
androidLibraryOptions: AndroidLibraryOptions,
compilationOptions: CompilationOptions,
) {
applyAndroidCommon(
androidOptions = androidLibraryOptions,
compilationOptions = compilationOptions
)
..
}
private fun Project.applyAndroidCommon(
androidOptions: AndroidOptions,
compilationOptions: CompilationOptions,
) =
with(commonExtension) {
..
compileOptions {
sourceCompatibility = androidOptions.javaVersion
targetCompatibility = androidOptions.javaVersion
}
applyKotlinOptions(compilationOptions)
..
}
Expondo as novas APIs
Agora, atualizaremos nosso KPlatformPlugin.kt
com as novas definições:
fun Project.androidApp(
compilationOptionsBuilder: CompilationOptionsBuilder.() -> Unit = { },
appOptionsBuilder: AndroidAppOptionsBuilder.() -> Unit = { },
) = applyAndroidApp(
androidAppOptions = AndroidAppOptionsBuilder().apply(appOptionsBuilder).build(),
compilationOptions = CompilationOptionsBuilder().apply(compilationOptionsBuilder).build()
)
fun Project.androidLibrary(
compilationOptionsBuilder: CompilationOptionsBuilder.() -> Unit = { },
libraryOptionsBuilder: AndroidLibraryOptionsBuilder.() -> Unit = { },
) = applyAndroidLibrary(
androidLibraryOptions = AndroidLibraryOptionsBuilder().apply(libraryOptionsBuilder).build(),
compilationOptions = CompilationOptionsBuilder().apply(compilationOptionsBuilder).build()
)
fun Project.jvmLibrary(builderAction: CompilationOptionsBuilder.() -> Unit = { }) =
applyJvmLibrary(
compilationOptions = CompilationOptionsBuilder().apply(builderAction).build()
)
Criando um módulo JVM e aplicando as decorações da plataforma
1 - Dentro de core
, criaremos um novo módulo chamado threading
.
2 - Inclua esse novo módulo no settings.gradle.kts
:
include(":app", ":features:details", ":features:home", ":core:designsystem", ":core:threading")
3 - Sincronize o projeto. Em seguida, crie um arquivo build.gradle.kts
e configure as opções desse módulo:
import com.rsicarelli.kplatform.jvmLibrary
plugins {
kotlin("jvm")
}
jvmLibrary()
dependencies {
api(libs.kotlinx.coroutines.core)
testApi(libs.kotlinx.coroutines.test)
}
Sucesso!
A IDE informará se essa biblioteca é pura JVM.
Embora eu esteja usando o IntelliJ, o Android Studio também exibirá um ícone diferente
No próximo artigo, aprenderemos a customizar nossas compilações para incorporar algumas das funcionalidades experimentais do compilador Kotlin.
Top comments (0)