くうと徒然なるままに

モバイルアプリを作りながらバックエンドも作っています。

Android アプリのパッケージ依存管理と大変だったところ。

導入

Android アプリ開発をしていると各Module ごとに依存しているライブラリのバージョンや種類がバラバラになって後で苦労することは多々あると思います。

私の認識では、依存するライブラリを集中管理するためのテクニック。について書きます。

英語でググるdependency management とかいう名前で呼ばれているようです。

業務等では普通に使われているのにウェブ上で言及されることは少ないので書いていきます。 また、DroidKaigi2019 のアプリを参考にしている部分もあります。

前提知識

Android アプリの Library 等でパッケージを導入するためには、以下のように定義することでリモートにあるパッケージを落としてきて使うことができるようになります。

// main package で使うための宣言 a.k.a.main
implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
// Unit Test で使うための宣言 a.k.a. test
testImplementation 'junit:junit:4.12'
// Android Test で使うための宣言 a.k.a. androidTest
androidTestImplementation 'androidx.test:runner:1.1.0-alpha4'

今回の手法を適用させると以下のように簡潔かつバージョンアップなどの変更に強い形で記述することができるようになります。

implementation Dep.androidx.constraintLayout
testImplementation Dep.test.junit
androidTestImplementation Dep.androidTest.androidx.testRunner

手順

1. buildSrc modukeを追加しその中に記述していく

buildSrc moduleのなかに記述していきます。
なぜ、その名前なのかは正直理解できてないです。慣習的なものなのかそれともGradle に起因するものなのか。

2. build.gradle を build.gradle.kts に変更する

いわゆる Kotlin Gradle DSL とか呼ばれるやつです。

内容は以下のようにしました。

import org.gradle.kotlin.dsl.`kotlin-dsl`

plugins {
    `kotlin-dsl`
}

repositories {
    jcenter()
}

3. 依存性するパッケージの内容物を記述していく

buildSrc moduke の中に 普通のKotlin ファイルを追加し、その中に記述していきます。

object を作成しその中にパッケージ名を入れた変数を定義していきます。

自分の場合は以下のようにしました。

@file:Suppress("unused")

package dependencies

object Dep {
    object kotlin {
        val stdLib = "org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.3.20"

    }

    object androidx {
        val constraintLayout = "androidx.constraintlayout:constraintlayout:1.1.3"
    }

    object test {
        val junit = "junit:junit:4.12"
    }

    object androidTest {
        object androidx {
            val testRunner = "androidx.test:runner:1.1.0-alpha4"
        }
    }
}

4. app module やその他の場所に buildSrc の内容を利用した依存を記述していく

app Module 等に入っている Build.gradle の中に記述していきます。

先述の通りに書けばいいのですが、一応再掲しておきます。

注意点としては、 import で 先ほど buildSrc に追加した Dep Object を 取り込みます。

手元の環境でも、DroidKaigi のアプリでも同様にDep の部分が赤文字になってしまうのですが、解決策知っている人いたら教えてください。

f:id:kuxumarin:20190205103214p:plain

import dependencies.Dep
---
dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    implementation Dep.kotlin.stdLib
    implementation Dep.androidx.constraintLayout
    testImplementation Dep.test.junit
    androidTestImplementation Dep.androidTest.androidx.testRunner
}

大変だったところ

setting.gradle に buildSrc を書いてしまった

一般的に module を追加したら setting.gradle に自動追記されるのでそこの部分で注意が必要です。
なぜ必要ないのか知っている人がいたら教えて欲しい...

buildSrc Module の Build.gradle.kts のリポジトリ指定を忘れていた

タイトルの通りです。
ネットに落ちてるコードでは書いてないことが多々ありますが、必要です。