TRY ANDROID DEV

Android アプリ開発のコーディングネタ。あとエンジニアとしての活動

DroidKaigi 2019 official appを読んでみる①:Gradle Kotlin DSL

背景

  • DroidKaigi 2019 のofficial appが公開されている:参照
  • せっかくだしコントリビュートしたいなと思ったけど思った以上に皆新しい技術使っててよくわからない。。
  • とりあえず一つずつ理解することにする。

DroidKaigi 2019 official app のbuild.gradle

build.gradleをみてみると以下のように記載してありました。

dependencies {
 ・
 ・
 ・
    implementation Dep.Kotlin.stdlibJvm
    api Dep.Kotlin.coroutines
    implementation Dep.Kotlin.androidCoroutinesDispatcher
    implementation Dep.OkHttp.okio
}

調べてみるとKotlin-DSLとbuildSrcを利用したdependencyの管理みたいです。
もうここからよくわからないので調べてみます。

DSLとは

ドメイン特化言語Domain Specific Language)のことで、 特定の問題解決のために専用の構文が用意されているようなことを言うみたい。

Gradleの例に当てはめて考えてみると、 今まで利用されていたのは「Groovy-DSL」、つまりビルドスクリプトを書くのにGroovy言語が専用に構文を用意してくれていたよう。

今回は、ビルドスクリプトを書くためにkotlinが専用の構文を用意してくれたのでこれを使ってみようということですね。

Gradle Kotlin DSL

DroidKaigi公式をみてみると、次のようにしています。

  1. build.gradleは通常通りGroovyで記載。
  2. ただし、dependenciesはbuildSrc/Dep.ktにまとめており、build.gradleはこちらを参照している模様。
dependencies {
    implementation Dep.AndroidX.Navigation.runtime
    implementation Dep.AndroidX.Navigation.fragment
    implementation Dep.AndroidX.Navigation.ui
    implementation Dep.AndroidX.Navigation.runtimeKtx
    implementation Dep.AndroidX.Navigation.fragmentKtx
}

buildSrc:dependencies/Dev.kt

object Dep {
    object AndroidX {
        object Navigation {
            val version = "1.0.0-alpha08"
            val runtime = "android.arch.navigation:navigation-runtime:$version"
            val runtimeKtx = "android.arch.navigation:navigation-runtime-ktx:$version"
            val fragment = "android.arch.navigation:navigation-fragment:$version"
            val ui = "android.arch.navigation:navigation-ui:$version"
            val fragmentKtx = "android.arch.navigation:navigation-fragment-ktx:$version"
            val uiKtx = "android.arch.navigation:navigation-ui-ktx:$version"
        }
    }
}

これはbuildSrcでのdependences管理方法で、gradleの公式ドキュメントに載ってました。
Organizing Gradle Projects

この管理をするとIDEの補完サポート(オートコンプリート)が受けられるみたいですね!
マルチモジュール化でどんどん依存関係が煩雑になってくるので、これはありがたいです。

サンプルを作成してみる。

実際に作成してみました。

  1. file -> new -> package で「buildSrc」パッケージを作成
  2. ①の構成になるようにファイルを作成
  3. build.gradle.ktsには②のように記載
  4. Dep.ktは自分の管理しやすいように。今回はDroidKaigiを真似て作成。
  5. Syncする
  6. Dep.ktを使いたいモジュールのbuild.gradleにimport dependencies.Depを記載
  7. Dep.ktのオブジェクトを参照可能! f:id:off2white:20190115132749p:plain

①:パッケージ構成

├── build.gradle.kts(root)
├── buildSrc
│   ├── build.gradle.kts
│   └── src
│       ├── main
│       │   └── dependencies
│       │              └── Dep.kt

②: build.gradle.kts

plugins {
    `kotlin-dsl`
}

感想

できたけど、なんか以下のように補完してもらってもめっちゃ候補出てくる... 思ってたのと違う... f:id:off2white:20190115132150p:plain

誰かいい感じの設定ご存知でしたら教えてください。

ハマったところ

  • buildSrcを通常のandroid library として生成して'com.andriod.library' not found が発生。

    • buildSrcディレクトリはインクルードビルドで、gradleがbuildSrcを見つけると勝手にビルドしてくれる。適当な名前じゃダメみたい。
    • そんな特殊なディレクトリなので、モジュール扱いするとエラーが発生する。でもnot found エラーにすることなくない...?
    • DroidKaigi アプリみてこんな感じだろうと思い込みで作業したら1時間のハマり。公式を読めとあれほど。。。
  • ktsのファイル名をgradle.ktsにしたら、他モジュールで全然参照できなかった。

    • build.gradle.ktsでないとダメみたい。
  • sync すると Failed to notify project evaluation listener. が発生

    • 当初はandroid libraryモジュールとして作成していたのでSettings.gradleにモジュール名が含まれており、これが原因だった模様。
    • Settings.gradleから名前を削除したらビルドできた。

今回作成したサンプルコード

github.com

2019/1/16 追記

以下の環境にしたらbuildSrcのオブジェクトが参照できなくなった。。。

謎です。わかったらまた追記します。