visible true

技術的なメモを書く

DoroidKaigi conference app 2023を読んでいく 1

DoroidKaigi 2023の公式アプリのリポジトリが公開されましたね。 github.com

Androidアプリケーション開発から離れて久しいので、まずは最新のトレンドや技術について学ぶために、このプロジェクトを使って実際に手を動かしながら、気になる部分を調べてメモしていくことにしました。コントリビュートはできそうならやろうかなと考えています。

build-logicってなに

プロジェクトをAndroid Studioで開き、ビルドして動かしつつプロジェクト内を眺めると、何やら見慣れないモジュールが。

app-iosとapp-androidというモジュールから、プロジェクト全体がKotlin Multiplatformぽいことは推測できます。また、core, featureは共通のロジックやUIとかだろうな〜とも推測できます。ではbuild-logicとは一体なんなのか?

中身をチラッと眺めてもよくわかりませんでした。いっぱい書いてて大変やな〜というのが第一印象。

build-logicはGradleのComposing buildsを用いた共通のビルド設定

まずは根本から辿っていこう、ということで、Project rootのbuild.gradle.ktssettings.gradle.kts を読みました。するとsettings.gradle.kts に次のような記述がありました

https://github.com/DroidKaigi/conference-app-2023/blob/main/settings.gradle.kts#L2

pluginManagement {
    includeBuild("build-logic")
    ...
}

includeBuildってなんだろう?と調べてみるとComposing buildsというページが見つかりました。

docs.gradle.org

includeBuildに指定したmoduleの設定を取り込めるもの、と理解しました。詳細を見るとなんだか難しそうなので、conference-app-2023での使い方に着目してみると、次のようにpluginをregisterしている記述が見つかりました。

https://github.com/DroidKaigi/conference-app-2023/blob/main/build-logic/build.gradle.kts#L35

register("androidApplication") {
    id = "droidkaigi.primitive.androidapplication"
    implementationClass = "io.github.droidkaigi.confsched2023.primitive.AndroidApplicationPlugin"
}
register("android") {
    id = "droidkaigi.primitive.android"
    implementationClass = "io.github.droidkaigi.confsched2023.primitive.AndroidPlugin"
}

idはpluginIdで、implementationClassはpluginの動作を記述しているクラスのFQCNです。対応するクラスの実装を見てみると、build.gradleに記述しそうなことが書いてあります。

例: https://github.com/DroidKaigi/conference-app-2023/blob/main/build-logic/src/main/kotlin/io/github/droidkaigi/confsched2023/primitive/AndroidComposePlugin.kt

Jetpack ComposeやDagger Hiltなんかは結構色んな設定を書くので、各種モジュールに毎回宣言するのは大変ですもんね。pluginとしてまとめて、モジュール側でpluginをapplyする形にすることで、共通化をしているようです。マルチモジュールでは必須の仕組みと言えそうですね。

ちょっとした気になり

build-logicは、プロジェクト全体に、configをまとめたplugin群を定義する仕組みと分かりました。実際にfeature moduleを覗いてみると、pluginをapplyしています。

https://github.com/DroidKaigi/conference-app-2023/blob/main/feature/about/build.gradle.kts

plugins {
    id("droidkaigi.convention.androidfeature")
}

android.namespace = "io.github.droidkaigi.confsched2023.feature.about"

dependencies {
    implementation(projects.core.designsystem)
    implementation(projects.core.ui)
    implementation(projects.core.model)
    testImplementation(projects.core.testing)

    implementation(libs.androidxCoreKtx)
    implementation(libs.composeUi)
    implementation(libs.composeHiltNavigtation)
    implementation(libs.composeMaterial)
    implementation(libs.composeUiToolingPreview)
    implementation(libs.androidxLifecycleLifecycleRuntimeKtx)
    implementation(libs.androidxActivityActivityCompose)
    implementation(libs.composeMaterialIcon)
    androidTestImplementation(libs.composeUiTestJunit4)
    debugImplementation(libs.composeUiTooling)
    debugImplementation(libs.composeUiTestManifest)
}

droidkaigi.convention.androidfeatureにはandroidアプリに関するpluginがいくつかバンドルされています。さてそこで気になるのは、モジュールのdependenciesの記述です。droidkaigi.convention.androidfeatureにはJetpack ComposeやDagger Hilt、テスティングなどのdependenciesが含まれています。droidkaigi.convention.androidfeatureを利用するモジュールで再度dependenciesを宣言する必要は無い気がしますが、実際には宣言が書かれていました。

試しに重複しているdependenciesを除去して、クリーンビルドしたら、無事ビルドが成功しました。なんとなくrepository公開に向けてわーっと作ってこの辺りの重複除去はまだ特にやってない、ということかなと解釈しました。

libs.versions.tomlってなに

モジュールのdependenciesを見ると、

testImplementation(projects.core.testing)
implementation(libs.androidxCoreKtx)

といった具合にlibs.androidxCoreKtxという謎の変数を参照しています。これは一体どこから来るのか?

gradle/libs.versions.tomlというファイルを見つけました。中身はなんだかpackage.json.lockだとかGemfile.lockみたいな雰囲気。

conference-app-2023/gradle/libs.versions.toml at main · DroidKaigi/conference-app-2023 · GitHub

[versions]
androidGradlePlugin = "8.1.0"
# For updating Kotlin and Compose Compiler version, see:
# https://github.com/JetBrains/compose-multiplatform/blob/master/VERSIONING.md#kotlin-compatibility
# https://developer.android.com/jetpack/androidx/releases/compose-kotlin?#pre-release_kotlin_compatibility
kotlin = "1.9.0"

androidxCore = "1.10.1"
androidDesugarJdkLibs = "2.0.3"
compose = "1.5.0"
compose-jb = "1.4.3"
composeCompiler = "1.5.1"
...

これはGradleのバージョンカタログという機能のようです。 developer.android.com

build-logic/settings.gradle.ktsで当該tomlファイルを読み込む記述をしていて、これによりプロジェクト全体でバージョンカタログの変数を参照できるようになっているようです。

https://github.com/DroidKaigi/conference-app-2023/blob/main/build-logic/settings.gradle#L10

バージョンの変数宣言はとっ散らかる感じがあったので、こういった仕組みは便利ですね。

next

Gradleの設定やモジュール構成とKotlin Multiplatformの関係性がまだ理解しきれていません。次回はKotlin Multiplatformの構成について学び、各モジュールの関係について調べようと思います。