Androidプラットフォーム - パート13: "純粋JVM"モジュールの追加
🌱 ブランチ: 13/jvm-only-modules
🔗 リポジトリ: github.com/rsicarelli/kotlin-gradle-android-platform
⬅️ 前の記事: パート12: Androidライブラリのビルド時間の最適化
➡️ 次の記事: パート14: Kotlinコンパイラの実験的な機能を活用する
前回の記事では、Android Gradle Plugin(AGP)のさまざまな機能を無効にすることで、Androidモジュールのコンパイルを最適化しました。
今回の記事では、「純粋JVM」モジュール(java-library
)と「Androidライブラリ」モジュール(com.android.library
)の違いについて話します。また、これらの機能をサポートするためにプラットフォームを拡張します。
純粋JVMモジュールとは何か?
純粋JVMモジュールは、Java Virtual Machine (JVM)のみを使用して実行されるモジュールです。つまり、Androidと直接関連または依存していません。
簡単に言えば、Androidモジュールの特有の複雑さがない純粋なJavaモジュールです。
その結果、コンパイルが効率的になります。なぜなら、これらのモジュールはAGPのコンパイルプロセスを通じていないからです。
純粋JVMモジュールを使うシチュエーション
-
ビジネスロジック: Androidに直接依存しない計算、バリデーション、リストの操作などのビジネスロジックに関連するコードに。
-
汎用ライブラリ: Androidプロジェクトと純粋なKotlin/JVMプロジェクトの両方で使用することができるライブラリを開発している場合に。
-
コアモジュール: データベース、ネットワーク、ログ記録に関連するモジュールは、純粋なKotlin/JVMで構築できます。
純粋JVMモジュールを受け入れるためにプラットフォームを装飾する
新しいエントリーポイントとして jvmLibrary()
を追加し、それを applyJvmLibrary()
で装飾する提案です。
1 - kotlin.kt
ファイルに fun Project.applyJvmLibrary
関数を作成します。
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 - これからさまざまなカスタマイズを適用するために、モジュールが個別にコンパイルを設定できるようにします。Options
をそのままにしないために build-logic/src/../options
フォルダを作成し、AndroidOptions.kt
をそこへ移動します。
CompilationsOptions
クラスを作成し、内部を宣言します。
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 - applyJvmLibrary()
関数を 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 - 関数 applyKotlinOptions
のシグネチャを変更し、共通の 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)
// ...
}
新しいAPIを公開する
KPlatformPlugin.kt
を新しい定義で更新します。
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()
)
JVMモジュールの作成とプラットフォームのデコレーション適用
1 - core
内に threading
という新しいモジュールを作成します。
2 - この新しいモジュールを settings.gradle.kts
に含めます。
include(":app", ":features:details", ":features:home", ":core:designsystem", ":core:threading")
3 - プロジェクトを同期した後、build.gradle.kts
ファイルを作成し、このモジュールのオプションを設定します。
import com.rsicarelli.kplatform.jvmLibrary
plugins {
kotlin("jvm")
}
jvmLibrary()
dependencies {
api(libs.kotlinx.coroutines.core)
testApi(libs.kotlinx.coroutines.test)
}
成功!
IDEはこのライブラリが純粋なJVMであると知らせます。
IntelliJを使用していますが、Android Studioでも異なるアイコンが表示されます。
次の記事では、 Kotlinコンパイラの実験機能のいくつかを包含するためにコンパイルをどのようにカスタマイズするかを学びます。
こちらの記事はdev.toの良い記事を日本人向けに翻訳しています。
https://dev.to/rsicarelli/android-plataforma-parte-13-incluindo-modulos-puro-jvm-4f61