Android Studio の Gradle ビルドシステムを使うと、外部バイナリや他のライブラリ モジュールを依存関係として簡単にビルドに含めることができます。依存関係は、マシン上またはリモート リポジトリで見つけることができます。推移的な依存関係が宣言されている場合、それも自動的に含まれます。このページでは、Android Plugin for Gradle に特有の動作と構成を含め、Android プロジェクトで依存関係を使用する方法について詳しく説明します。Gradle の依存関係の概念をより深く理解するには、依存関係管理に関する Gradle のガイドもご覧ください。ただし、Android プロジェクトでは、このページで定義されている依存関係構成のみを使用する必要があることにご注意ください。
依存関係のタイプ
プロジェクトに依存関係を追加するには、モジュールの build.gradle
ファイルの dependencies
ブロックで、implementation
などの依存関係構成を指定します。
たとえば、アプリ モジュール用の次の build.gradle
ファイルには、3 つのタイプの依存関係が含まれています。
Groovy
plugins { id 'com.android.application' } android { ... } dependencies { // Dependency on a local library module implementation project(':mylibrary') // Dependency on local binaries implementation fileTree(dir: 'libs', include: ['*.jar']) // Dependency on a remote binary implementation 'com.example.android:app-magic:12.3' }
Kotlin
plugins { id("com.android.application") } android { ... } dependencies { // Dependency on a local library module implementation(project(":mylibrary")) // Dependency on local binaries implementation(fileTree(mapOf("dir" to "libs", "include" to listOf("*.jar")))) // Dependency on a remote binary implementation("com.example.android:app-magic:12.3") }
これらはそれぞれ異なるタイプのライブラリ依存関係をリクエストします。
- ローカル ライブラリ モジュールへの依存関係
-
Groovy
implementation project(':mylibrary')
Kotlin
implementation(project(":mylibrary"))
これは、「mylibrary」という名前の Android ライブラリ モジュールへの依存関係を宣言しています(この名前は、
settings.gradle
ファイルのinclude:
で定義されているライブラリ名と一致する必要があります)。アプリのビルド時に、ビルドシステムはライブラリ モジュールをコンパイルし、結果としてコンパイルされた内容をアプリにパッケージ化します。 - ローカル バイナリへの依存関係
-
Groovy
implementation fileTree(dir: 'libs', include: ['*.jar'])
Kotlin
implementation(fileTree(mapOf("dir" to "libs", "include" to listOf("*.jar"))))
Gradle は、プロジェクトの
module_name/libs/
ディレクトリ内の JAR ファイルへの依存関係を宣言します(Gradle はbuild.gradle
ファイルへの相対パスを読み取るため)。または、次のように個々のファイルを指定することもできます。
Groovy
implementation files('libs/foo.jar', 'libs/bar.jar')
Kotlin
implementation(files("libs/foo.jar", "libs/bar.jar"))
- リモート バイナリへの依存関係
-
Groovy
implementation 'com.example.android:app-magic:12.3'
Kotlin
implementation("com.example.android:app-magic:12.3")
これは、実際には次のコードの省略形です。
Groovy
implementation group: 'com.example.android', name: 'app-magic', version: '12.3'
Kotlin
implementation(group = "com.example.android", name = "app-magic", version = "12.3")
これは、「com.example.android」名前空間グループ内に存在するバージョン 12.3 の「app-magic」ライブラリへの依存関係を宣言しています。
注: このようなリモートの依存関係には、Gradle がライブラリを検索するための適切なリモート リポジトリの宣言が必要です。ライブラリがまだローカルに存在しない場合、Gradle はビルドでライブラリが必要になったとき(たとえば [Sync Project with Gradle Files]
をクリックしたときやビルドを実行したとき)に、リモートサイトからライブラリを取得します。
コンパイル時に AGP 依存関係に依存する場合は、それを明示的な依存関係として追加してください。AGP は内部で api/implementation
構成を使用するので、一部のアーティファクトがコンパイル クラスパスから削除されてコンパイル クラスパスが変更されることがあります。
ネイティブ依存関係
Android Gradle プラグイン 4.0 以降では、このページに記載されている方法でネイティブ依存関係をインポートすることもできます。
ネイティブ ライブラリを公開する AAR に依存することで、externalNativeBuild
によって使用されるビルドシステムがそれらを自動的に使用できるようになります。コードからそれらのライブラリにアクセスするには、ネイティブ ビルド スクリプト内でライブラリにリンクする必要があります。このページのネイティブ依存関係を使用するをご覧ください。
依存関係構成
dependencies
ブロックで、複数の依存関係構成のうちの 1 つ(上記の implementation
など)を使用して、ライブラリ依存関係を宣言できます。それぞれの依存関係構成は、依存関係の使用方法についてのさまざまな指示を Gradle に与えます。以下の表は、Android プロジェクトで依存関係に使用できる各構成の説明です。この表では、Android Gradle プラグイン 3.0.0 で非推奨になった構成との比較も示しています。
構成 | 動作 |
---|---|
implementation |
Gradle は依存関係をコンパイル クラスパスに追加し、また依存関係をビルド出力にパッケージ化します。ただし、モジュールで implementation 依存関係を構成している場合、Gradle はモジュールの依存関係がコンパイル時に他のモジュールに通知されないようにします。つまり、他のモジュールは実行時にならないとこの依存関係を利用できません。
この依存関係構成を |
api |
Gradle は依存関係をコンパイル クラスパスとビルド出力に追加します。モジュールに api 依存関係が含まれている場合、Gradle はモジュールの依存関係を他のモジュールに推移的にエクスポートします。この場合、他のモジュールは実行時とコンパイル時の両方で依存関係を利用できるようになります。
この構成の動作は |
compileOnly |
Gradle は、コンパイル クラスパスのみに依存関係を追加します(ビルド出力には追加されません)。これは、Android モジュールを作成しており、コンパイル時には依存関係が必要であるものの、実行時にはなくても構わない場合に便利です。
この構成を使用する場合は、実行時に依存関係が利用可能かどうかを確認する条件をライブラリ モジュールに含める必要があります。次に、依存関係が提供されていなくても構成が機能するように、その動作をスムーズに切り替える必要があります。これは、重要でない一時的な依存関係を追加しないことにより最終的なアプリのサイズを削減するのに役立ちます。この構成の動作は 注: |
runtimeOnly |
Gradle は、実行時に使用できるように、ビルド出力だけに依存関係を追加します。つまり、コンパイル クラスパスには追加されません。
この構成の動作は apk (非推奨)と同様です。
|
annotationProcessor |
アノテーション プロセッサのライブラリへの依存関係を追加するには、 JAR ファイルに次のファイルが含まれる場合、Android Gradle プラグインは、依存関係がアノテーション プロセッサであると想定します。
プラグインは、コンパイル クラスパス上のアノテーション プロセッサを検出すると、ビルドエラーを生成します。 注: Kotlin プロジェクトでアノテーション プロセッサの依存関係を宣言する場合は、kapt を使用する必要があります。 |
lintChecks |
プロジェクトのビルド時に Gradle に実行させる lint チェックを含めるには、この構成を使用します。 注: Android Gradle プラグイン 3.4.0 以降を使用している場合、この依存関係構成は、Android ライブラリ プロジェクトに lint チェックをパッケージ化しなくなりました。AAR ライブラリに lint チェックの依存関係を含めるには、下記の |
lintPublish |
Gradle で lint チェックを lint.jar ファイルにコンパイルして AAR にパッケージ化するには、Android ライブラリ プロジェクトでこの構成を使用します。これにより、AAR を使用するプロジェクトもそれらの lint チェックを適用するようになります。以前に lintChecks 依存関係構成を使用して公開 AAR に lint チェックを含めていた場合は、その依存関係を移行して、代わりに lintPublish 構成を使用する必要があります。
Groovydependencies { // Executes lint checks from the ':checks' project at build time. lintChecks project(':checks') // Compiles lint checks from the ':checks-to-publish' into a // lint.jar file and publishes it to your Android library. lintPublish project(':checks-to-publish') } Kotlindependencies { // Executes lint checks from the ":checks" project at build time. lintChecks(project(":checks")) // Compiles lint checks from the ":checks-to-publish" into a // lint.jar file and publishes it to your Android library. lintPublish(project(":checks-to-publish")) } |
apk
|
Gradle は、実行時に使用できるように、ビルド出力だけに依存関係を追加します。つまり、コンパイル クラスパスには追加されません。 この構成は非推奨です(AGP 1.0~4.2 では利用できます)。 |
compile
|
Gradle は、依存関係をコンパイル クラスパスとビルド出力に追加し、依存関係を他のモジュールにエクスポートします。この構成は非推奨です(AGP 1.0~4.2 では利用できます)。 |
provided
|
Gradle は、コンパイル クラスパスだけに依存関係を追加します(つまり、ビルド出力には追加されません)。この構成は非推奨です(AGP 1.0~4.2 では利用できます)。 |
上記のすべての構成は、すべてのビルド バリアントに依存関係を適用します。これに対し、特定のビルド バリアントのソースセットまたはテスト用のソースセットのみに依存関係を宣言する場合は、構成名の先頭を大文字にして、その先頭に対象のビルド バリアントまたはテスト用のソースセットの名前を付加する必要があります。
たとえば、implementation
依存関係を(リモート バイナリ依存関係を使用して)「free」プロダクト フレーバーだけに追加するには、次のようにします。
Groovy
dependencies { freeImplementation 'com.google.firebase:firebase-ads:9.8.0' }
Kotlin
dependencies { freeImplementation("com.google.firebase:firebase-ads:9.8.0") }
一方、プロダクト フレーバーとビルドタイプを組み合わせたバリアントに依存関係を追加する場合は、configurations
ブロックで構成名を初期化する必要があります。次のサンプルでは、runtimeOnly
依存関係を(ローカル バイナリ依存関係を使用して)「freeDebug」ビルド バリアントに追加しています。
Groovy
configurations { // Initializes a placeholder for the freeDebugRuntimeOnly dependency configuration. freeDebugRuntimeOnly {} } dependencies { freeDebugRuntimeOnly fileTree(dir: 'libs', include: ['*.jar']) }
Kotlin
// Initializes a placeholder for the freeDebugRuntimeOnly dependency configuration. val freeDebugRuntimeOnly by configurations.creating dependencies { freeDebugRuntimeOnly(fileTree(mapOf("dir" to "libs", "include" to listOf("*.jar")))) }
ローカルテストとインストルメンテーション テストに implementation
依存関係を追加するには、次のようにします。
Groovy
dependencies { // Adds a remote binary dependency only for local tests. testImplementation 'junit:junit:4.12' // Adds a remote binary dependency only for the instrumented test APK. androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1' }
Kotlin
dependencies { // Adds a remote binary dependency only for local tests. testImplementation("junit:junit:4.12") // Adds a remote binary dependency only for the instrumented test APK. androidTestImplementation("androidx.test.espresso:espresso-core:3.5.1") }
ただし、この状況では、一部の構成は効果がありません。たとえば、他のモジュールが androidTest
に依存できないため、androidTestApi
構成を使用すると、以下の警告が表示されます。
WARNING: Configuration 'androidTestApi' is obsolete and has been replaced with 'androidTestImplementation'.
アノテーション プロセッサを追加する
アノテーション プロセッサをコンパイル クラスパスに追加すると、次のようなエラー メッセージが表示されます。
Error: Annotation processors must be explicitly declared now.
このエラーを解決するには、annotationProcessor
を使用して依存関係を構成することにより、プロジェクトにアノテーション プロセッサを追加します。次に例を示します。
Groovy
dependencies { // Adds libraries defining annotations to only the compile classpath. compileOnly 'com.google.dagger:dagger:version-number' // Adds the annotation processor dependency to the annotation processor classpath. annotationProcessor 'com.google.dagger:dagger-compiler:version-number' }
Kotlin
dependencies { // Adds libraries defining annotations to only the compile classpath. compileOnly("com.google.dagger:dagger:version-number") // Adds the annotation processor dependency to the annotation processor classpath. annotationProcessor("com.google.dagger:dagger-compiler:version-number") }
注: Android Plugin for Gradle 3.0.0 以降、android-apt
プラグインはサポートが終了しました。
アノテーション プロセッサに引数を渡す
アノテーション プロセッサに引数を渡す必要がある場合は、モジュールのビルド構成で AnnotationProcessorOptions
ブロックを使用します。たとえば、プリミティブ データ型を Key-Value ペアとして渡す場合は、次のように argument
プロパティを使用できます。
Groovy
android { ... defaultConfig { ... javaCompileOptions { annotationProcessorOptions { argument 'key1', 'value1' argument 'key2', 'value2' } } } }
Kotlin
android { ... defaultConfig { ... javaCompileOptions { annotationProcessorOptions { arguments += mapOf("key1" to "value1", "key2" to "value2") } } } }
ただし、Android Gradle プラグイン 3.2.0 以降を使用している場合は、Gradle の CommandLineArgumentProvider
インターフェースを使用して、ファイルまたはディレクトリを表すプロセッサ引数を渡す必要があります。
アプリ デベロッパーやアノテーション プロセッサの作成者は CommandLineArgumentProvider
を使用することで、増分ビルド プロパティ型のアノテーションを各引数に適用して、増分ビルドとキャッシュに保存されたクリーンビルドの正確性やパフォーマンスを改善できます。
たとえば、次のクラスは CommandLineArgumentProvider
を実装し、プロセッサの各引数にアノテーションを追加しています。また、このサンプルは Groovy 言語の構文を使用し、モジュールの build.gradle
ファイルに直接組み込まれています。
Groovy
class MyArgsProvider implements CommandLineArgumentProvider { // Annotates each directory as either an input or output for the // annotation processor. @InputFiles // Using this annotation helps Gradle determine which part of the file path // should be considered during up-to-date checks. @PathSensitive(PathSensitivity.RELATIVE) FileCollection inputDir @OutputDirectory File outputDir // The class constructor sets the paths for the input and output directories. MyArgsProvider(FileCollection input, File output) { inputDir = input outputDir = output } // Specifies each directory as a command line argument for the processor. // The Android plugin uses this method to pass the arguments to the // annotation processor. @Override Iterable<String> asArguments() { // Use the form '-Akey[=value]' to pass your options to the Java compiler. ["-AinputDir=${inputDir.singleFile.absolutePath}", "-AoutputDir=${outputDir.absolutePath}"] } } android {...}
Kotlin
class MyArgsProvider( // Annotates each directory as either an input or output for the // annotation processor. @get:InputFiles // Using this annotation helps Gradle determine which part of the file path // should be considered during up-to-date checks. @get:PathSensitive(PathSensitivity.RELATIVE) val inputDir: FileCollection, @get:OutputDirectory val outputDir: File ) : CommandLineArgumentProvider { // Specifies each directory as a command line argument for the processor. // The Android plugin uses this method to pass the arguments to the // annotation processor. override fun asArguments(): Iterable<String> { // Use the form '-Akey[=value]' to pass your options to the Java compiler. return listOf("-AinputDir=${inputDir.singleFile.absolutePath}", "-AoutputDir=${outputDir.absolutePath}") } } android {...}
CommandLineArgumentProvider
を実装するクラスを定義したら、インスタンスを作成して、annotationProcessorOptions.compilerArgumentProvider
メソッドで Android プラグインに渡す必要があります。次に例を示します。
Groovy
// This is in your module's build.gradle file. android { defaultConfig { javaCompileOptions { annotationProcessorOptions { // Creates a new MyArgsProvider object, specifies the input and // output paths for the constructor, and passes the object // to the Android plugin. compilerArgumentProvider new MyArgsProvider(files("input/path"), new File("output/path")) } } } }
Kotlin
// This is in your module's build.gradle file. android { defaultConfig { javaCompileOptions { annotationProcessorOptions { // Creates a new MyArgsProvider object, specifies the input and // output paths for the constructor, and passes the object // to the Android plugin. compilerArgumentProvider(MyArgsProvider(files("input/path"), file("output/path"))) } } } }
CommandLineArgumentProvider
の実装を通じてビルドのパフォーマンスを改善する方法について詳しくは、Java プロジェクトのキャッシュをご覧ください。
アノテーション プロセッサによるエラーチェックを無効にする
コンパイル クラスパスの依存関係に不要なアノテーション プロセッサが含まれている場合は、build.gradle
ファイルに次の内容を追加することでエラーチェックを無効にできます。コンパイル クラスパスに追加するアノテーション プロセッサは、まだプロセッサ クラスパスに追加されていないことにご注意ください。
Groovy
android { ... defaultConfig { ... javaCompileOptions { annotationProcessorOptions { includeCompileClasspath false } } } }
Kotlin
android { ... defaultConfig { ... javaCompileOptions { annotationProcessorOptions { argument("includeCompileClasspath", "false") } } } }
Kotlin と kapt を使用する場合:
Groovy
android { ... defaultConfig { ... kapt { includeCompileClasspath false } } }
Kotlin
android { ... defaultConfig { ... kapt { includeCompileClasspath = false } } }
プロジェクトのアノテーション プロセッサをプロセッサ クラスパスに移行した後で問題が発生する場合は、includeCompileClasspath
を true
に設定して、コンパイル クラスパス上のアノテーション プロセッサを許可できます。ただし、このプロパティを true
に設定することは推奨されません。Android プラグインの将来のアップデートで、この設定は使用できなくなります。
推移的依存関係を除外する
アプリの規模が大きくなるにつれ、直接的な依存関係や推移的な依存関係(アプリがインポートしたライブラリが依存するライブラリ)など、多くの依存関係が含まれる可能性があります。不要になった推移的依存関係を除外するには、次のように exclude
キーワードを使用します。
Groovy
dependencies { implementation('some-library') { exclude group: 'com.example.imgtools', module: 'native' } }
Kotlin
dependencies { implementation("some-library") { exclude(group = "com.example.imgtools", module = "native") } }
推移的依存関係をテスト構成から除外する
テスト時に、特定の推移的な依存関係を除外する必要がある場合、上記のコードサンプルは期待どおりに動作しない可能性があります。これは、テスト構成(androidTestImplementation
など)がモジュールの implementation
構成を拡張するためです。つまり、Gradle がこの構成を解決するときは、常に implementation
依存関係が含まれます。
したがって、テストから推移的依存関係を除外するには、実行時に除外する必要があります。次に例を示します。
Groovy
android.testVariants.all { variant -> variant.getCompileConfiguration().exclude group: 'com.jakewharton.threetenabp', module: 'threetenabp' variant.getRuntimeConfiguration().exclude group: 'com.jakewharton.threetenabp', module: 'threetenabp' }
Kotlin
android.testVariants.all { compileConfiguration.exclude(group = "com.jakewharton.threetenabp", module = "threetenabp") runtimeConfiguration.exclude(group = "com.jakewharton.threetenabp", module = "threetenabp") }
注: 推移的依存関係を除外するセクションの元のコードサンプルに示されている依存関係ブロックで exclude
キーワードを使用して、テスト構成に固有で他の構成には含まれない推移的依存関係を省略することもできます。
Wear OS アプリの依存関係を構成する
Wear OS モジュールの依存関係を構成する方法は、他のモジュールの場合と同様です。つまり、Wear OS モジュールは、同じ依存関係構成(implementation
や compileOnly
など)を使用します。
Wear モジュールは、バリアント識別による依存関係の管理もサポートします。そのため、アプリのベース モジュールに Wear モジュールとの依存関係がある場合、ベース モジュールの各バリアントは、Wear モジュールの対応するバリアントを使用します。
リモート リポジトリ
ローカル ライブラリまたはファイルツリー以外の依存関係がある場合、Gradle は settings.gradle
ファイルの dependencyResolutionManagement { repositories {...} }
ブロックで指定されたすべてのオンライン リポジトリでファイルを探します。各リポジトリをリストした順序により、Gradle が各プロジェクトの依存関係を検索するリポジトリの順序が決まります。たとえば、ある依存関係がリポジトリ A とリポジトリ B の両方で利用可能で、リポジトリのリスト内で A が先に記述されている場合、Gradle はその依存関係をリポジトリ A からダウンロードします。
デフォルトでは、新規の Android Studio プロジェクトは、プロジェクトの settings.gradle
ファイルで、Google の Maven リポジトリと Maven セントラル リポジトリをリポジトリの場所として指定します。次に例を示します。
Groovy
dependencyResolutionManagement { repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS) repositories { google() mavenCentral() } }
Kotlin
dependencyResolutionManagement { repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS) repositories { google() mavenCentral() } }
ローカル リポジトリに含まれているものが必要な場合は、mavenLocal()
を使用してください。
Groovy
dependencyResolutionManagement { repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS) repositories { google() mavenCentral() mavenLocal() } }
Kotlin
dependencyResolutionManagement { repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS) repositories { google() mavenCentral() mavenLocal() } }
または、次のようにして特定の Maven リポジトリまたは Ivy リポジトリを宣言することもできます。
Groovy
dependencyResolutionManagement { repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS) repositories { maven { url 'https://repo.example.com/maven2' } maven { url 'file://local/repo/' } ivy { url 'https://repo.example.com/ivy' } } }
Kotlin
dependencyResolutionManagement { repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS) repositories { maven(url = "https://repo.example.com/maven2") maven(url = "file://local/repo/") ivy(url = "https://repo.example.com/ivy") } }
詳しくは、Gradle リポジトリ ガイドをご覧ください。
Google の Maven リポジトリ
以下の Android ライブラリの最新バージョンを Google の Maven リポジトリから入手できます。
- AndroidX ライブラリ
- アーキテクチャ コンポーネント ライブラリ
- Constraint Layout ライブラリ
- AndroidX Test
- データ バインディング ライブラリ
- Android Instant App ライブラリ
- Wear OS
- Google Play 開発者サービス
- Google Play 請求サービス ライブラリ
- Firebase
すべての利用可能なアーティファクトは、Google の Maven リポジトリ インデックスで確認できます(下のプログラムからのアクセスをご覧ください)。
上記のライブラリのいずれかをビルドに追加するには、最上位の build.gradle
ファイルに Google の Maven リポジトリを含めます。
Groovy
dependencyResolutionManagement { repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS) repositories { google() // If you're using a version of Gradle lower than 4.1, you must instead use: // maven { // url 'https://maven.google.com' // } // An alternative URL is 'https://dl.google.com/dl/android/maven2/'. } }
Kotlin
dependencyResolutionManagement { repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS) repositories { google() // If you're using a version of Gradle lower than 4.1, you must instead use: // maven { // url = "https://maven.google.com" // } // An alternative URL is "https://dl.google.com/dl/android/maven2/". } }
次に、目的のライブラリをモジュールの dependencies
ブロックに追加します。たとえば、appcompat ライブラリの場合は次のようになります。
Groovy
dependencies { implementation 'androidx.appcompat:appcompat:1.6.1' }
Kotlin
dependencies { implementation("com.android.support:appcompat-v7:28.0.0") }
ただし、上記のライブラリの古いバージョンを利用しようとして依存関係が解決されなかった場合、Maven リポジトリからはライブラリを入手できないため、オフライン リポジトリから入手する必要があります。
プログラムからのアクセス
Google の Maven アーティファクトにプログラムからアクセスするために、XML 形式のアーティファクト グループのリストを maven.google.com/master-index.xml から取得できます。そうすると、次のファイルから任意のグループのライブラリ名とバージョンを確認できます。
maven.google.com/group_path/group-index.xml
たとえば、android.arch.lifecycle グループのライブラリは、maven.google.com/android/arch/lifecycle/group-index.xml にリストされています。
次の場所から POM ファイルと JAR ファイルをダウンロードすることもできます。
maven.google.com/group_path/library/version/library-version.ext
例: maven.google.com/android/arch/lifecycle/compiler/1.0.0/compiler-1. 0.0.pom
SDK Manager のオフライン リポジトリ
Google Maven リポジトリから入手できないライブラリ(古いバージョンのライブラリなど)の場合は、SDK Manager からオフライン Google Repository パッケージをダウンロードする必要があります。
その後は通常どおり、dependencies
ブロックにライブラリを追加できます。
オフライン ライブラリは android_sdk/extras/
に保存されます。
Android Gradle プラグインのネイティブ依存関係
AAR ライブラリには、Android Gradle プラグインが使用できるネイティブ依存関係を含めることができます。AGP では、ネイティブ ライブラリをユーザーに公開する AAR を生成することもできます。
ネイティブ依存関係を使用する
Android Gradle プラグイン 4.0 以降では、build.gradle
ファイルでリンクされている AAR から C / C++ 依存関係をインポートできます。ネイティブ ビルドシステムは Gradle で自動的にこれらを利用できるようになりますが、固有のビルドシステムは、インポートされたライブラリとヘッダーを使用するように構成する必要があります。C / C++ 依存関係は AAR として配信されるため、一般的な AAR に関する以下のリンクが参考になります。
- 一般的な AAR のドキュメントと AAR をプロジェクトに統合する方法については(特に AAR をローカルの C / C++ 依存関係として使用する場合は)、Android ライブラリの作成をご覧ください。
build.gradle
ファイルに依存関係を追加する方法については(リモートの依存関係の場合は特に)ビルド依存関係の追加をご覧ください。
このドキュメントでは、ネイティブ ビルドシステムの構成方法を中心にして説明します。C / C++ 依存関係の AAR をプロジェクトの Gradle ビルド環境にすでに追加していることを前提とします。
AAR のネイティブ依存関係
Gradle モジュールの AAR 依存関係によって、アプリケーションで使用するネイティブ ライブラリを公開できます。AAR 内の prefab
ディレクトリには、ネイティブ依存関係のヘッダーとライブラリを含む Prefab パッケージが含まれます。
Prefab パッケージは 1 つ以上のモジュールで構成され、各依存関係は最大 1 つのパッケージを公開できます。Prefab モジュールは単一のライブラリで、共有ライブラリ、静的ライブラリ、ヘッダーのみのライブラリのいずれかになります。
ライブラリを使用するには、パッケージ名とモジュール名を公開する必要があります。通常、パッケージ名は Maven アーティファクト名と同じで、モジュール名はライブラリ名と同じにしますが、これは必須ではありません。依存関係のドキュメントを参照して、使用する名前を決定します。
ビルドシステムの構成
Android Gradle モジュールで prefab
機能を有効にする必要があります。
それには、モジュールの build.gradle
ファイルの android
ブロックに次のコードを追加します。
Groovy
buildFeatures { prefab true }
Kotlin
buildFeatures { prefab = true }
必要に応じて、プロジェクトの gradle.properties
ファイルでバージョンを構成します。
android.prefabVersion=2.0.0
通常は、選択した AGP のデフォルト バージョンがニーズに合致します。修正が必要なバグがある場合や追加したい新機能がある場合にのみ、別のバージョンを選択してください。
各依存関係は、Android.mk
ファイルをビルドに公開します。これらは import-module コマンドでインポートされます。このコマンドは、ビルドのインポート ディレクトリ内で指定したパス(import-add-path
で設定)を使用して Android.mk
ファイルを検索し、ビルドで使用するために定義したモジュールを公開します。たとえば、アプリケーションで libapp.so
を定義し、cURL を使用する場合、Android.mk
ファイルに以下を含める必要があります。
include $(CLEAR_VARS)
LOCAL_MODULE := libapp
LOCAL_SRC_FILES := app.cpp
LOCAL_SHARED_LIBRARIES := curl
include $(BUILD_SHARED_LIBRARY)
# If you don't need your project to build with NDKs older than r21, you can omit
# this block.
ifneq ($(call ndk-major-at-least,21),true)
$(call import-add-path,$(NDK_GRADLE_INJECTED_IMPORT_PATH))
endif
$(call import-module,prefab/curl)
明示的な import-add-path
は、r21 より前の NDK を使用する場合にのみ必要です。r21 では、NDK_GRADLE_INJECTED_IMPORT_PATH
が自動的にインポートパスに追加されます。
これで app.cpp
が #include "curl/curl.h"
を行えるようになり、ビルド時に libapp.so
が自動的に libcurl.so
にリンクされて、libcurl.so
がアプリに組み込まれます。
AAR でネイティブ ライブラリを公開する
ネイティブ AAR を作成する機能は、最初に AGP 4.1 で追加されました。
ネイティブ ライブラリをエクスポートするには、ライブラリ プロジェクトの build.gradle
ファイルの android
ブロックに次の行を追加します。
Groovy
buildFeatures { prefabPublishing true } prefab { mylibrary { headers "src/main/cpp/mylibrary/include" } myotherlibrary { headers "src/main/cpp/myotherlibrary/include" } }
Kotlin
buildFeatures { prefabPublishing = true } prefab { create("mylibrary") { headers = "src/main/cpp/mylibrary/include" } create("myotherlibrary") { headers = "src/main/cpp/myotherlibrary/include" } }
この例では、ndk-build または CMake 外部ネイティブ ビルドの mylibrary
ライブラリと myotherlibrary
ライブラリが、ビルドによって生成された AAR にパッケージ化され、それぞれが指定されたディレクトリから依存先にヘッダーをエクスポートします。
依存関係の順序
依存関係をリストする順序は、それぞれの優先度を示します。たとえば、1 番目のライブラリは 2 番目のライブラリより優先度が高く、2 番目は 3 番目より優先度が高くなります。この順序は、ライブラリからアプリにリソースをマージする場合、またはマニフェスト要素をマージする場合に重要です。
たとえば、プロジェクトで以下を宣言したとします。
LIB_A
への依存関係とLIB_B
への依存関係(この順序)LIB_A
はLIB_C
とLIB_D
に依存(この順序)LIB_B
もLIB_C
に依存
この場合、依存関係の順序を展開すると次のようになります。
LIB_A
LIB_D
LIB_B
LIB_C
これにより、LIB_A
と LIB_B
はいずれも LIB_C
より優先され、LIB_D
は LIB_B
よりも優先度が高くなります。これは、依存元の LIB_A
の優先度が LIB_B
より高いためです。
異なるプロジェクトのソースや依存関係のマニフェストをマージする方法については、複数のマニフェスト ファイルをマージするをご覧ください。
モジュールの依存関係を表示する
直接的な依存関係の中には、独自の依存関係を持つものもあります。これは、推移的な依存関係と呼ばれています。推移的な各依存関係を手動で宣言しなくても、Gradle ではこれらの依存関係が自動的に収集され、追加されます。Android Plugin for Gradle では、Gradle が特定のモジュールに対して解決する依存関係のリストを表示するタスクを提供しています。
また、各モジュールのレポートでは、ビルド バリアント、テスト ソースセット、クラスパスに基づいて依存関係がグループ化されます。以下に、アプリ モジュールのデバッグビルド バリアントのランタイム クラスパスと、インストゥルメント化されたテスト ソースセットのコンパイル クラスパスのサンプル レポートを示します。
debugRuntimeClasspath - Dependencies for runtime/packaging
+--- :mylibrary (variant: debug)
+--- com.google.android.material:material:1.0.0@aar
+--- androidx.appcompat:appcompat:1.0.2@aar
+--- androidx.constraintlayout:constraintlayout:1.1.3@aar
+--- androidx.fragment:fragment:1.0.0@aar
+--- androidx.vectordrawable:vectordrawable-animated:1.0.0@aar
+--- androidx.recyclerview:recyclerview:1.0.0@aar
+--- androidx.legacy:legacy-support-core-ui:1.0.0@aar
...
debugAndroidTest
debugAndroidTestCompileClasspath - Dependencies for compilation
+--- androidx.test.ext:junit:1.1.0@aar
+--- androidx.test.espresso:espresso-core:3.1.1@aar
+--- androidx.test:runner:1.1.1@aar
+--- junit:junit:4.12@jar
...
このタスクを実行する手順は次のとおりです。
- [View] > [Tool Windows] > [Gradle] を選択します(または、ツール ウィンドウ バーの Gradle アイコン
をクリックします)。
- AppName > [Tasks] > [android] の順に展開し、androidDependencies をダブルクリックします。Gradle がタスクを実行すると、[Run] ウィンドウが開いて出力が表示されます。
Gradle での依存関係の管理について詳しくは、Gradle ユーザーガイドの依存関係管理の基本をご覧ください。
依存関係解決エラーを修正する
アプリのプロジェクトに複数の依存関係を追加すると、それらの直接的または推移的な依存関係の間に競合が発生する可能性があります。Android Gradle プラグインは競合を適切に解決しようと試みますが、一部の競合によりコンパイル時エラーまたは実行時エラーが発生することがあります。
どの依存関係がエラーの原因になっているかを調査するには、アプリの依存関係ツリーを検査し、複数回登場する依存関係または競合するバージョンを含む依存関係を探します。
重複する依存関係を簡単に見つけられない場合は、次のように Android Studio の UI を使用して、重複するクラスを含む依存関係を探します。
- メニューバーから [Navigate] > [Class] を選択します。
- ポップアップ検索ダイアログで、[Include non-project items] チェックボックスがオンになっていることを確認します。
- ビルドエラーで表示されるクラスの名前を入力します。
- このクラスを含む依存関係がないか結果を検査します。
次のセクションでは、依存関係の解決で発生する可能性のあるさまざまなタイプのエラーと、その修正方法について説明します。
重複クラスエラーを修正する
ランタイム クラスパスにクラスが複数回登場すると、次のようなエラーが発生します。
Program type already present com.example.MyClass
このエラーは通常、以下のいずれかの状況で発生します。
- バイナリ依存関係に含まれているライブラリが、直接的な依存関係としてアプリにも含まれている場合。たとえば、アプリでライブラリ A とライブラリ B に対する直接的な依存関係が宣言されているものの、すでにライブラリ A のバイナリにライブラリ B が含まれている場合などです。
- この問題を解決するには、ライブラリ B を直接的な依存関係から削除します。
- アプリにローカル バイナリ依存関係があり、同じライブラリに対するリモート バイナリ依存関係も存在する場合。
- この問題を解決するには、バイナリ依存関係の一方を削除します。
クラスパス間の競合を修正する
Gradle がコンパイル クラスパスを解決する際、まずランタイム クラスパスが解決され、その結果によりコンパイル クラスパスに追加する依存関係のバージョンが判定されます。つまり、ランタイム クラスパスにより、それ以降のクラスパスで同じ依存関係に必要なバージョン番号が決まります。
アプリのランタイム クラスパスは、アプリのテスト APK のランタイム クラスパスでの依存関係をマッチングする際に、Gradle が必要とするバージョン番号の決定にも関係します。クラスパスの階層関係を図 1 に示します。
図 1. 複数のクラスパスに登場する依存関係のバージョン番号のマッチングは、この階層に基づいて行われる必要があります。
たとえば、implementation
依存関係構成を使用するバージョンの依存関係がアプリに含まれ、runtimeOnly
構成を使用する別のバージョンの依存関係がライブラリ モジュールに含まれる場合、同じ依存関係の異なるバージョンが複数のクラスパスに登場する競合が発生する可能性があります。
3.3.0 以降の Android Gradle プラグインは、ランタイム クラスパスとコンパイル クラスパスへの依存関係を解決する際に、それ以降の特定のバージョン競合を自動的に修正しようと試みます。たとえば、ランタイム クラスパスにライブラリ A バージョン 2.0 が含まれ、コンパイル クラスパスにライブラリ A バージョン 1.0 が含まれている場合、プラグインはコンパイル クラスパスへの依存関係を自動的にライブラリ A バージョン 2.0 にアップデートして、エラーを回避します。
ただし、ランタイム クラスパスにライブラリ A バージョン 1.0 が含まれ、コンパイル クラスパスにライブラリ A バージョン 2.0 が含まれている場合、プラグインはコンパイル クラスパスへの依存関係をライブラリ A バージョン 1.0 にダウングレードしないため、以下のようなエラーが発生します。
Conflict with dependency 'com.example.library:some-lib:2.0' in project 'my-library'. Resolved versions for runtime classpath (1.0) and compile classpath (2.0) differ.
この問題を解決するには、以下のいずれかを行います。
- 必要なバージョンの依存関係を
api
依存関係としてライブラリ モジュールに含めます。これにより、ライブラリ モジュールでは依存関係を宣言するだけになりますが、アプリ モジュールはその API に推移的にアクセスします。 - または、両方のモジュールに依存関係を宣言します。この場合、各モジュールが同じバージョンの依存関係を使用する必要があります。プロジェクト全体でプロパティの構成を行うことを考えて、プロジェクト全体で各依存関係のバージョンが一致するようにしてください。
カスタム ビルドロジックを適用する
このセクションでは、Android Gradle プラグインの拡張や独自のプラグインの作成に役立つトピックについて詳しく説明します。
バリアント依存関係をカスタム ロジックに公開する
ライブラリに、他のプロジェクトまたはサブプロジェクトで使用したい機能が含まれていることがあります。ライブラリの公開とは、ライブラリが他で使用できるようにするためのプロセスです。ライブラリは、コンパイル時および実行時にアクセスできる依存関係を制御できます。
各クラスパスの推移的な依存関係を保持するために、2 つの異なる構成を使用します。これらはライブラリの利用元により、以下のようにして使用される必要があります。
variant_nameApiElements
: この構成は、コンパイル時に使用できる推移的な依存関係を保持します。variant_nameRuntimeElements
: この構成は、実行時に使用できる推移的な依存関係を保持します。
異なる構成間の関係について詳しくは、Java ライブラリ プラグイン 構成をご覧ください。
カスタム依存関係の解決方針
同じライブラリの 2 つのバージョンへの依存関係がプロジェクトに含まれていることがあります。その場合、依存関係の競合が発生することがあります。たとえば、プロジェクトがモジュール A のバージョン 1 とモジュール B のバージョン 2 に依存し、モジュール A がモジュール B のバージョン 3 に推移的に依存している場合、依存関係のバージョン競合が発生します。
こうした競合を解決するため、Android Gradle プラグインは、「依存関係グラフで同じモジュールの異なるバージョンを検出したときは、デフォルトでバージョン番号が最も大きいものを選択する」という依存関係の解決方針をとります。
ただし、この方針は常に意図したとおりの結果をもたらすとは限りません。依存関係の解決方針をカスタマイズするには、次の構成を使用して、タスクで必要なバリアントの特定の依存関係を解決します。
variant_nameCompileClasspath
: この構成では、指定したバリアントのコンパイル クラスパスのための解決方針が指定されます。variant_nameRuntimeClasspath
: この構成では、指定したバリアントのランタイム クラスパスのための解決方針が指定されます。
Android Gradle プラグインには、各バリアントの構成オブジェクトにアクセスするための getter が用意されています。これにより、バリアント API を使用して依存関係の解決をクエリできます。次に例を示します。
Groovy
android { applicationVariants.all { variant -> // Return compile configuration objects of a variant. variant.getCompileConfiguration().resolutionStrategy { // Use Gradle's ResolutionStrategy API // to customize how this variant resolves dependencies. ... } // Return runtime configuration objects of a variant. variant.getRuntimeConfiguration().resolutionStrategy { ... } // Return annotation processor configuration of a variant. variant.getAnnotationProcessorConfiguration().resolutionStrategy { ... } } }
Kotlin
android { applicationVariants.all { // Return compile configuration objects of a variant. compileConfiguration.resolutionStrategy { // Use Gradle's ResolutionStrategy API // to customize how this variant resolves dependencies. ... } // Return runtime configuration objects of a variant. runtimeConfiguration.resolutionStrategy { ... } // Return annotation processor configuration of a variant. annotationProcessorConfiguration.resolutionStrategy { ... } } }
Google Play Console の依存関係情報
AGP 4.0.0 以降を使用してアプリをビルドすると、アプリにコンパイルされるライブラリ依存関係を記述したメタデータがプラグインによって含められます。アプリがアップロードされると、Google Play Console はこのメタデータを検査して、アプリが使用している SDK と依存関係の既知の問題に関するアラートを発信します。また、場合によっては、その問題を解決するための実用的なフィードバックも提供します。
データは圧縮され、Google Play の署名鍵で暗号化されて、リリースアプリの署名ブロックに保存されます。この依存関係ファイルを保持して、安全で優れたユーザー エクスペリエンスのために役立てることをおすすめします。なお、この情報を共有したくない場合は、モジュールの build.gradle
ファイルに次の dependenciesInfo
ブロックを含めることでオプトアウトできます。
android {
dependenciesInfo {
// Disables dependency metadata when building APKs.
includeInApk = false
// Disables dependency metadata when building Android App Bundles.
includeInBundle = false
}
}
依存関係に関する Google のポリシーと潜在的な問題について詳しくは、アプリでサードパーティの SDK を使用する場合のサポートページをご覧ください。
SDK 分析情報
Android Studio では、Google Play SDK Index で作成者によって古いとマークされた公開 SDK について、build.gradle
ファイルや [Project Structure] ダイアログで lint 警告が表示されます。古いバージョンを使用すると Google Play Console に今後公開できなくなる可能性があるため、こうした警告は該当する依存関係を更新するためのシグナルになります。