9
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

男坂Advent Calendar 2020

Day 2

[Android]Gradleの依存関係のimplementation/apiの使い分け

Last updated at Posted at 2020-12-01

Gradleの依存関係のimplementation/apiの使い分けについて。
Android公式の説明は、正しく詳細なのだが、中々理解できなかった。
ようやくimplementation/apiの使い分けが腑に落ちたので、まとめる。

最初は、ユースケースで考えた方が分かりやすいと思う。

  • ライブラリモジュールの場合
    • ライブラリのAPIに使う依存ライブラリ -> "api"
    • そうでない依存ライブラリ -> "implementation"
  • アプリモジュールの場合1
    • "implementation"を使う。"api"でも動作変わらないが、あえて使う理由はない。

この後の説明長いが、ここを抑えておけば、読まなくても害はなさそう。

ケーススタディ

自作ライブラリに、以下のAPIがあるとする。

data class User(val id: String, val name: String)

class UserRepository {
    fun getUser(id: Int): LiveData<User> {
        ...
    }

    fun add(user: User) { ... }
}

このケースでは、自作ライブラリを使うモジュールをコンパイルする際に、LiveDataのライブラリが必要になる。なので、自作ライブラリの依存関係の設定では"api"を使う2

自作ライブラリのbuild.gradleの記述例。

dependencies {
    api 'androidx.lifecycle:lifecycle-livedata-ktx:2.2.0'
}

もし、UserRepository#getUser()がprivateであれば、自作ライブラリを使うモジュールのコンパイルにLiveDataライブラリは不要である。なので、自作ライブラリの依存関係で"implementation"を指定する。

詳細

アプリ -> 自作ライブラリ -> LiveDataライブラリという方向で依存しているとする。
このときの、自作ライブラリのbuild.gradleの記述を考える。

LiveDataライブラリへの依存関係を"implementation"と"api"のどちらに指定しようが、自作ライブラリにとっては違いはない。自作ライブラリのコンパイル時からLiveDataライブラリは必要とみなされる。一方で、アプリからの見え方には違いが出る。"implementation"を使った場合は、実行時から必要なライブラリと扱われ、"api"を使った場合はコンパイル時から必要という扱いになる。

アプリへの依存関係の見せ方は、自作ライブラリをmavenリポジトリにデプロイしたときのpomの内容で決まる(~/.gradleを探すと外部ライブラリのpom見れる)。pomを見てみると、"implementation"は"runtime" scope、"api"は"compile" scopeに対応していることが分かる。

この記事に、図があって分かりやすい。
https://qiita.com/tkhs0604/items/7afe40599af2354eb2ad

蛇足

"api"の依存関係が推移する理由。
アプリ -> A -> B -> Cと依存していて、AのAPIにB、BのAPIにCを含むとする。
当然、AのAPIにCも含まれるので、アプリのコンパイルにはA, Bだけでなく、Cも必要ということになる。
これが公式の説明で言うところの、依存関係が推移するという意味。

LiveDataを自作ライブラリのクラスやinterfaceでwrapすれば、自作ライブラリからLiveDataへの依存関係に"implementation"が使えるようになる。LiveDataライブラリとその依存ライブラリが、コンパイル時に不要になるので、アプリのビルドは早くなる3

  1. 正確には、他のモジュールから参照されないモジュール。

  2. "implementation"を使った場合、自作ライブラリを使う側のモジュールにも、LiveDataのライブラリへの依存関係を記述しないといけない。

  3. 普通はアプリモジュールもLiveDataを使うので、例が微妙。LiveDataライブラリを汎用性のないライブラリで置き換えて考えると分かりやすいかも。

9
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
9
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?