ビルド依存関係の追加

Android Studio の Gradle ビルドシステムを使うと、外部バイナリや他のライブラリ モジュールを依存関係として簡単にビルドに含めることができます。依存関係は、マシン上またはリモート リポジトリで見つけることができます。推移的な依存関係が宣言されている場合、それも自動的に含まれます。このページでは、Android Plugin for Gradle に特有の動作や設定を含め、Android プロジェクトで依存関係を使う方法について詳しく説明します。Gradle の依存関係に関する概念レベルの詳しいガイドについては、依存関係管理のための Gradle ガイドもご覧ください。ただし、Android プロジェクトでは、このページで定義されている依存関係コンフィグレーションしか使用できない点に注意してください。

依存関係のタイプ

プロジェクトに依存関係を追加するには、build.gradle ファイルの dependencies で、implementation などの依存関係コンフィグレーションを指定します。

たとえば、次に示すアプリ モジュールの build.gradle ファイルには 3 種類の依存関係が含まれています。

apply plugin: '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'
    }
    

これらはそれぞれ異なるタイプのライブラリ依存関係をリクエストします。

ローカル ライブラリ モジュール依存関係
implementation project(':mylibrary')

これは、「mylibrary」という名前の Android ライブラリ モジュールへの依存関係を宣言しています(この名前は、settings.gradle ファイルの include: で定義されているライブラリ名と一致する必要があります)。アプリのビルド時に、ビルドシステムはライブラリ モジュールをコンパイルし、その結果を APK にパッケージ化します。

ローカル バイナリ依存関係
implementation fileTree(dir: 'libs', include: ['*.jar'])

Gradle は、プロジェクトの module_name/libs/ ディレクトリ内の JAR ファイルへの依存関係を宣言します(Gradle は build.gradle ファイルへの相対パスを読み取るため)。

または、次のように個々のファイルを指定することもできます。

implementation files('libs/foo.jar', 'libs/bar.jar')
リモート バイナリ依存関係
implementation 'com.example.android:app-magic:12.3'

これは、実際には次の省略形です。

    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] をクリックしたときや、ビルドを実行したときなど)。

依存関係コンフィグレーション

dependencies ブロックでは、複数の依存関係コンフィグレーションのうちのいずれか(前述の implementation など)を使ってライブラリ依存関係を宣言できます。それぞれの依存関係コンフィグレーションは、依存関係の使用方法について Gradle にさまざまな指示を与えます。以下の表で、Android プロジェクトで依存関係に使用できる各コンフィグレーションについて説明します。この表は、Android Gradle プラグイン 3.0.0 でサポートが終了したコンフィグレーションとの対応も示しています。

新しいコンフィグレーション サポートが終了したコンフィグレーション 動作
implementation compile Gradle は依存関係をコンパイル クラスパスに追加し、また依存関係をビルド出力にパッケージ化します。ただし、モジュールで implementation 依存関係が設定されている場合、Gradle はコンパイル時に、モジュールの依存関係が他のモジュールに通知されないようにします。つまり、他のモジュールは実行時にならないとこの依存関係を利用できません。

この依存関係コンフィグレーションを api または compile(サポート終了済み)の代わりに使用すると、ビルドシステムで再コンパイルが必要なモジュールの数が削減されるため、ビルド時間が大幅に短縮されます。たとえば、implementation 依存関係の API に変更が発生した場合、Gradle はその依存関係とそれに直接的に依存するモジュールのみを再コンパイルします。大半のアプリとテスト モジュールに、このコンフィグレーションを使用することをおすすめします。

api compile Gradle は依存関係をコンパイル クラスパスとビルド出力に追加します。モジュールに api 依存関係が含まれている場合、Gradle はモジュールの依存関係を他のモジュールに推移的にエクスポートします。この場合、他のモジュールは実行時とコンパイル時の両方で依存関係を利用できるようになります。

このコンフィグレーションの動作は compile(サポート終了済み)と同様ですが、他の上流モジュールに推移的にエクスポートする必要がある依存関係のみを対象として慎重に使用する必要があります。その理由は、api 依存関係の外部 API が変更された場合、Gradle はコンパイル時に、その依存関係にアクセスできるすべてのモジュールを再コンパイルするためです。つまり、大量の api 依存関係が存在すると、ビルド時間が大幅に増加する可能性があります。ライブラリ モジュールでは、分離されたモジュールに依存関係の API を公開する場合を除き、implementation 依存関係を使用する必要があります。

compileOnly provided Gradle は、コンパイル クラスパスのみに依存関係を追加します(ビルド出力には追加されません)。これは、Android モジュールを作成しており、コンパイル時には依存関係が必要であるものの、実行時にはなくても構わない場合に便利です。

このコンフィグレーションを使用する場合は、実行時に依存関係が利用できるかどうかを確認する条件をライブラリ モジュールに追加する必要があります。また、依存関係が提供されなくても動作するように、スムーズに動作を切り替える必要もあります。このコンフィグレーションを使用すると、必要ではない一時的な依存関係が含まれなくなるため、最終的な APK のサイズの縮小に役立ちます。このコンフィグレーションの動作は provided(サポート終了済み)と同様です。

runtimeOnly apk Gradle は、実行時に使用できるようにビルド出力のみに依存関係を追加します。つまり、コンパイル クラスパスには追加されません。このコンフィグレーションの動作は apk(サポート終了済み)と同様です。
annotationProcessor compile アノテーション プロセッサのライブラリに依存関係を追加するには、annotationProcessor コンフィグレーションを使用してアノテーション プロセッサ クラスパスに依存関係を追加する必要があります。これは、このコンフィグレーションを使用すると、コンパイル クラスパスとアノテーション プロセッサ クラスパスが別々になり、ビルドのパフォーマンスが向上するためです。Gradle はコンパイル クラスパスにアノテーション プロセッサがあると、ビルド時間に悪影響を及ぼすコンパイル回避を無効にします(Gradle 5.0 以降では、コンパイル クラスパスにあるアノテーション プロセッサは無視されます)。

JAR ファイルに
META-INF/services/javax.annotation.processing.Processor ファイルが含まれている場合、Android Gradle プラグインは依存関係をアノテーション プロセッサとみなします。プラグインがコンパイル クラスパスでアノテーション プロセッサを検出すると、ビルドエラーが生成されます。
lintChecks プロジェクトのビルド時に Gradle で実行する lint チェックを含めるには、このコンフィグレーションを使用します。

注: Android Gradle プラグイン 3.4.0 以降を使用している場合、この依存関係コンフィグレーションでは、Android ライブラリ プロジェクトに lint チェックをパッケージ化しなくなりました。AAR ライブラリに lint チェックの依存関係を含めるには、下記の lintPublish コンフィグレーションを使用します。

lintPublish Gradle で lint チェックを lint.jar ファイルにコンパイルして AAR にパッケージ化するには、Android ライブラリ プロジェクトでこのコンフィグレーションを使用します。これにより、AAR を使用するプロジェクトでその lint チェックを適用することもできます。以前に lintChecks 依存関係コンフィグレーションを使用して公開 AAR に lint チェックを含めていた場合は、これらの依存関係を移行して、代わりに lintPublish コンフィグレーションを使用する必要があります。

    dependencies {
      // 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')
    }

上記のコンフィグレーションにより、すべてのビルド バリアントに依存関係が適用されます。これに対し、特定のビルド バリアントのソースセットまたはテスト用のソースセットのみに依存関係を宣言したい場合は、コンフィグレーション名の先頭を大文字にして、その先頭に対象のビルド バリアントまたはテスト用のソースセットの名前を付加する必要があります。

たとえば、「free」プロダクト フレーバーのみに(リモート バイナリ依存関係を使って)implementation 依存関係を追加する場合は、次のようにします。

dependencies {
        freeImplementation 'com.google.firebase:firebase-ads:9.8.0'
    }
    

ただし、プロダクト フレーバーとビルドタイプを組み合わせたバリアントに依存関係を追加したい場合は、configurations ブロックでコンフィグレーション名を初期化する必要があります。次のサンプルでは、「freeDebug」ビルド バリアントに(ローカル バイナリ依存関係を使って)runtimeOnly 依存関係を追加しています。

configurations {
        // Initializes a placeholder for the freeDebugRuntimeOnly dependency
        // configuration.
        freeDebugRuntimeOnly {}
    }

    dependencies {
        freeDebugRuntimeOnly fileTree(dir: 'libs', include: ['*.jar'])
    }
    

ローカルのテストやインストゥルメント テストに implementation 依存関係を追加する場合は、次のようになります。

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 'com.android.support.test.espresso:espresso-core:3.0.2'
    }
    

ただしこの状況では、一部のコンフィグレーションは効果がありません。たとえば、他のモジュールが androidTest に依存することはできないため、androidTestApi コンフィグレーションを使用すると、以下の警告が表示されます。

    WARNING: Configuration 'androidTestApi' is obsolete and has been replaced with
    'androidTestImplementation'.
    

アノテーション プロセッサの追加

アノテーション プロセッサをコンパイル クラスパスに追加すると、次のようなエラー メッセージが表示されます。

    Error: Annotation processors must be explicitly declared now.
    

このエラーを解決するには、次のように annotationProcessor を使用して、プロジェクトにアノテーション プロセッサを追加するよう依存関係を設定します。

    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 プロパティを使用できます。

android {
        ...
        defaultConfig {
            ...
            javaCompileOptions {
                annotationProcessorOptions {
                    argument "key1", "value1"
                    argument "key2", "value2"
                }
            }
        }
    }
    

ただし、Android Gradle プラグイン 3.2.0 以降を使用している場合は、Gradle の CommandLineArgumentProvider インターフェースを使用して、ファイルまたはディレクトリを表すプロセッサ引数を渡す必要があります。

アノテーション プロセッサの作成者は CommandLineArgumentProvider を使用することで、増分ビルド プロパティ型のアノテーションを各引数に適用して、増分ビルドとキャッシュされたクリーンビルドの正確性とパフォーマンスを改善できます。

たとえば、次のクラスは CommandLineArgumentProvider を実装し、プロセッサの各引数にアノテーションを追加しています。また、このサンプルは Groovy 言語の構文を使用し、モジュールの build.gradle ファイルに直接組み込まれています。

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 {...}
    

CommandLineArgumentProvider を実装するクラスを作成したら、そのクラスを初期化して、次に示すように annotationProcessorOptions.compilerArgumentProvider プロパティを使用して Android プラグインに渡す必要があります。

// 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"))
                }
            }
        }
    }
    

CommandLineArgumentProvider の実装を通じてビルドのパフォーマンスを改善する方法について詳しくは、Java プロジェクトのキャッシュをご覧ください。

アノテーション プロセッサによるエラーチェックの無効化

コンパイル クラスパスの依存関係に不要なアノテーション プロセッサが含まれている場合は、build.gradle ファイルに次の内容を追加することでエラーチェックを無効にできます。コンパイル クラスパスに追加するアノテーション プロセッサは、まだプロセッサ クラスパスに追加されていない点に注意してください。

android {
        ...
        defaultConfig {
            ...
            javaCompileOptions {
                annotationProcessorOptions {
                    includeCompileClasspath false
                }
            }
        }
    }
    

プロジェクトのアノテーション プロセッサをプロセッサ クラスパスに移行した後に問題が発生する場合は、includeCompileClasspathtrue に設定することで、コンパイル クラスパスのアノテーション プロセッサを許容できます。ただし、このプロパティを true に設定することは推奨されません。Android プラグインの将来のアップデートで、この設定は使用できなくなります。

推移的な依存関係の除外

アプリの規模が大きくなるにつれ、直接的な依存関係や推移的な依存関係(アプリがインポートしたライブラリが依存するライブラリ)など、多くの依存関係が含まれる可能性があります。不要になった推移的な依存関係を除外するには、次のように exclude キーワードを使用します。

dependencies {
        implementation('some-library') {
            exclude group: 'com.example.imgtools', module: 'native'
        }
    }
    

テスト コンフィグレーションからの推移的な依存関係の除外

テスト時に、特定の推移的な依存関係を除外する必要がある場合、上記のコードサンプルは期待どおりに動作しない可能性があります。これは、テスト コンフィグレーション(androidTestImplementation など)がモジュールの implementation コンフィグレーションを拡張するためです。つまり、Gradle がコンフィグレーションを解決するときに、implementation 依存関係が常に含まれます。

よって、テスト時に推移的な依存関係を除外するには、次のようにして実行時に除外します。

android.testVariants.all { variant ->
        variant.getCompileConfiguration().exclude group: 'com.jakewharton.threetenabp', module: 'threetenabp'
        variant.getRuntimeConfiguration().exclude group: 'com.jakewharton.threetenabp', module: 'threetenabp'
    }
    

注: 依存関係の除外セクションの元のコードサンプルに示されている依存関係ブロックで exclude キーワードを使用して、テスト コンフィグレーションに固有で、他のコンフィグレーションに含まれていない推移的な依存関係を省略することもできます。

バリアント識別による依存関係の管理の使用

Android プラグイン 3.0.0 以降に含まれている新しい依存関係メカニズムでは、ライブラリの使用時に自動でバリアントのマッチングを行います。つまり、アプリの debug バリアントによって自動的にライブラリの debug バリアントが使われます。これはフレーバーの使用時にも当てはまるため、アプリの freeDebug バリアントによってライブラリの freeDebug バリアントが使用されることになります。

プラグインを正確にバリアントとマッチさせるためには、直接マッチできないインスタンスにはマッチする代替手段を提供する必要があります。アプリで「staging」というビルドタイプを設定しているにもかかわらず、そのライブラリ依存関係の 1 つに「staging」タイプが含まれていない場合、プラグインでアプリの「staging」バージョンをビルドしようとしたときに、どのバージョンのライブラリを使用すべきかを判断できません。そのため、次のようなエラー メッセージが表示されます。

    Error:Failed to resolve: Could not resolve project :mylibrary.
    Required by:
        project :app
    

バリアントのマッチングに関連するビルドエラーの解決

アプリと依存関係との直接的なバリアント マッチングが不可能な状況において、Gradle での処理方法を制御するには、プラグインに含まれる DSL 要素が便利です。バリアント識別依存関係マッチングに関連する特定のビルドエラーを解決する際に使用する DSL プロパティを決めるには、以下の表を参考にしてください。

ビルドエラーの原因解決策

ライブラリ依存関係に含まれていないビルドタイプがアプリに含まれている

たとえば、アプリには「staging」ビルドタイプが含まれているが、依存関係に含まれているビルドタイプは「debug」と「release」のみの場合などです。

なお、アプリに含まれていないビルドタイプがライブラリ依存関係に含まれている場合は、特に問題ありません。ライブラリ依存関係側にあるビルドタイプをプラグインで要求することはあり得ないためです。

次のように matchingFallbacks を使用して、特定のビルドタイプの代わりにマッチングするタイプを指定します。


    // In the app's build.gradle file.
    android {
        buildTypes {
            debug {}
            release {}
            staging {
                // Specifies a sorted list of fallback build types that the
                // plugin should try to use when a dependency does not include a
                // "staging" build type. You may specify as many fallbacks as you
                // like, and the plugin selects the first build type that's
                // available in the dependency.
                matchingFallbacks = ['debug', 'qa', 'release']
            }
        }
    }
    

アプリとそのライブラリ依存関係の両方に存在する特定のフレーバー ディメンションにおいて、ライブラリに含まれていないフレーバーがアプリに含まれている。

たとえば、アプリとそのライブラリ依存関係の両方に「tier」フレーバー ディメンションが存在するが、アプリの「tier」フレーバー ディメンションには「free」と「paid」というフレーバーが含まれているのに対し、依存関係の同じフレーバー ディメンションには「demo」と「paid」というフレーバーしか含まれていない場合などです。

なお、アプリとそのライブラリ依存関係の両方に存在する特定のフレーバー ディメンションにおいて、アプリに含まれていないプロダクト フレーバーがライブラリ依存関係に含まれている場合は、特に問題ありません。ライブラリ依存関係側にあるフレーバーをプラグインで要求することはあり得ないためです。

次のように matchingFallbacks を使用して、アプリの「free」プロダクト フレーバーの代わりにマッチングするフレーバーを指定します。


    // In the app's build.gradle file.
    android {
        defaultConfig{
        // Do not configure matchingFallbacks in the defaultConfig block.
        // Instead, you must specify fallbacks for a given product flavor in the
        // productFlavors block, as shown below.
      }
        flavorDimensions 'tier'
        productFlavors {
            paid {
                dimension 'tier'
                // Because the dependency already includes a "paid" flavor in its
                // "tier" dimension, you don't need to provide a list of fallbacks
                // for the "paid" flavor.
            }
            free {
                dimension 'tier'
                // Specifies a sorted list of fallback flavors that the plugin
                // should try to use when a dependency's matching dimension does
                // not include a "free" flavor. You may specify as many
                // fallbacks as you like, and the plugin selects the first flavor
                // that's available in the dependency's "tier" dimension.
                matchingFallbacks = ['demo', 'trial']
            }
        }
    }
    

アプリに含まれていないフレーバー ディメンションがライブラリ依存関係に含まれている。

たとえば、ライブラリ依存関係には「minApi」ディメンション用のフレーバーが含まれているが、アプリには「tier」ディメンション用のフレーバーしか含まれていない場合などです。つまり、アプリの「freeDebug」バージョンをビルドする場合、プラグインでは「minApi23Debug」と「minApi18Debug」のどちらのバージョンの依存関係を使用すべきかを判断できません。

なお、ライブラリ依存関係に含まれていないフレーバー ディメンションがアプリに含まれている場合は、特に問題ありません。プラグインでは、ライブラリ依存関係に存在するディメンションのみのフレーバーをマッチングするためです。たとえば、依存関係に ABI のディメンションが含まれていない場合、アプリの「freeX86Debug」バージョンは単に、依存関係の「freeDebug」バージョンを使用します。

次のサンプルに示すように、defaultConfig ブロックで missingDimensionStrategy を使用して、見つからなかった各ディメンションの中からプラグインで選択すべきデフォルトのフレーバーを指定します。また、productFlavors ブロック内で選択肢をオーバーライドして、存在しないディメンションに対してフレーバーごとに異なるマッチング方針を指定することもできます。


    // In the app's build.gradle file.
    android {
        defaultConfig{
        // Specifies a sorted list of flavors that the plugin should try to use from
        // a given dimension. The following tells the plugin that, when encountering
        // a dependency that includes a "minApi" dimension, it should select the
        // "minApi18" flavor. You can include additional flavor names to provide a
        // sorted list of fallbacks for the dimension.
        missingDimensionStrategy 'minApi', 'minApi18', 'minApi23'
        // You should specify a missingDimensionStrategy property for each
        // dimension that exists in a local dependency but not in your app.
        missingDimensionStrategy 'abi', 'x86', 'arm64'
        }
        flavorDimensions 'tier'
        productFlavors {
            free {
                dimension 'tier'
                // You can override the default selection at the product flavor
                // level by configuring another missingDimensionStrategy property
                // for the "minApi" dimension.
                missingDimensionStrategy 'minApi', 'minApi23', 'minApi18'
            }
            paid {}
        }
    }
    

Wear OS アプリの依存関係の設定

Wear OS モジュールの依存関係の設定は、他のモジュールの場合と同様です。つまり、implementationcompileOnly など、同じ依存関係コンフィグレーションを使用します。

Wear モジュールでは、バリアント識別による依存関係の管理も使用できます。そのため、アプリの基本モジュールに Wear モジュールとの依存関係がある場合、基本モジュールの各バリアントは、Wear モジュールの対応するバリアントを使用します。1 つの Wear モジュールとしか依存関係がない簡単なアプリをビルドしていて、そのモジュールが基本モジュールと同じバリアントを設定している場合、基本モジュールの build.gradle ファイルに次のように wearApp コンフィグレーションを指定する必要があります。

dependencies {
        // If the main and Wear app modules have the same variants,
        // variant-aware dependency management automatically matches
        // variants of the main app module with that of the wear module.
        wearApp project(':wearable')
    }
    

複数の Wear モジュールがあり、アプリのフレーバーごとに異なる Wear モジュールを指定する場合は、以下のように flavorWearApp コンフィグレーションを使用して指定できます(ただし、wearApp コンフィグレーションを使用する他の依存関係を含めることはできません)。

dependencies {
        paidWearApp project(':wear1')
        demoWearApp project(':wear1')
        freeWearApp project(':wear2')
    }
    

リモート リポジトリ

ローカルのライブラリやファイルツリー以外の依存関係がある場合、Gradle は build.gradle ファイルの repositories で指定されたすべてのオンライン リポジトリでファイルを探します。リストでのリポジトリの配置順により、各プロジェクトの依存関係について、Gradle がリポジトリを検索する順番が決まります。たとえば、ある依存関係がリポジトリ A とリポジトリ B の両方で使用でき、リストで A が最初に記述されている場合、Gradle はその依存関係をリポジトリ A からダウンロードします。

新規の Android Studio プロジェクトではデフォルトで、プロジェクトの最上位の build.gradle ファイルで、以下に示すように Google の Maven リポジトリと JCenter がリポジトリの場所として指定されています。

allprojects {
        repositories {
            google()
            jcenter()
        }
    }
    

Maven セントラル リポジトリから取得するものがある場合は、mavenCentral() を追加します。ローカル リポジトリの場合は、mavenLocal() を使用します。

allprojects {
        repositories {
            google()
            jcenter()
            mavenCentral()
            mavenLocal()
        }
    }
    

または、次のようにして特定の Maven または Ivy リポジトリを宣言することもできます。

allprojects {
        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 リポジトリから入手できます。

すべての利用可能なアーティファクトは、Google の Maven リポジトリ インデックスで確認できます(下のプログラムからのアクセスをご覧ください)。

これらのライブラリのいずれかをビルドに追加するには、最上位の build.gradle ファイルに Google の Maven リポジトリを含めます。

allprojects {
        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 ライブラリの場合は次のようになります。

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 リポジトリ パッケージをダウンロードする必要があります。

その後は通常どおり、dependencies ブロックにライブラリを追加できます。

オフライン ライブラリは android_sdk/extras/ に保存されます。

依存関係の順序

依存関係を記述する順序は、それぞれの優先度を示します。最初のライブラリは 2 番目より優先度が高く、2 番目は 3 番目より優先度が高い、といった具合です。この順序は、ライブラリからアプリにリソースを統合する場合や、マニフェスト要素を統合する場合に重要になります。

たとえば、プロジェクトで以下の宣言がされているとします。

  • LIB_A への依存関係と LIB_B への依存関係(この順序)
  • LIB_ALIB_CLIB_D に依存(この順序)
  • LIB_BLIB_C に依存

この場合、依存関係の順序を展開すると次のようになります。

  1. LIB_A
  2. LIB_D
  3. LIB_B
  4. LIB_C

これにより、LIB_ALIB_B はどちらも LIB_C より優先され、LIB_DLIB_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
    ...
    

このタスクを実行する手順は次のとおりです。

  1. [View] > [Tool Windows] > [Gradle] を選択します(または、ツール ウィンドウ バーの [Gradle] をクリックします)。
  2. [AppName] > [Tasks] > [android] の順に展開し、androidDependencies をダブルクリックします。Gradle がタスクを実行すると、[Run] ウィンドウが開いて出力が表示されます。

Gradle での依存関係の管理について詳しくは、Gradle ユーザーガイドの依存関係管理の基本をご覧ください。

依存関係の解決でのエラーの修正

アプリのプロジェクトに複数の依存関係を追加すると、それらの直接的または推移的な依存関係の間に競合が発生する可能性があります。Android Gradle プラグインは競合を適切に解決しようとしますが、一部の競合によりコンパイル時エラーまたは実行時エラーが発生することがあります。

どの依存関係がエラーの原因になっているかを調査するには、アプリの依存関係ツリーを検査し、複数回登場する依存関係や競合するバージョンを含む依存関係を探します。

重複する依存関係を簡単に見つけられない場合は、次のように Android Studio の UI を使用して、重複するクラスを含む依存関係を探します。

  1. メニューバーから [Navigate] > [Class] を選択します。
  2. ポップアップ検索ダイアログで、[Include non-project items] チェックボックスがオンになっていることを確認します。
  3. ビルドエラーで表示されるクラスの名前を入力します。
  4. このクラスを含む依存関係がないか結果を検査します。

次のセクションでは、依存関係の解決で発生する可能性のあるさまざまなタイプのエラーと、その修正方法について説明します。

重複クラスエラーの修正

ランタイム クラスパスにクラスが複数回登場すると、次のようなエラーが発生します。

    Program type already present com.example.MyClass
    

このエラーは通常、以下のいずれかの状況で発生します。

  • バイナリ依存関係に含まれているライブラリが、直接的な依存関係としてアプリにも含まれている場合。たとえば、アプリでライブラリ A とライブラリ B に対する直接的な依存関係が宣言されており、ライブラリ A のバイナリにライブラリ B が含まれている場合などです。
    • この問題を解決するには、ライブラリ B を直接的な依存関係から削除します。
  • アプリにローカル バイナリ依存関係があり、同じライブラリに対するリモート バイナリ依存関係も存在する場合。
    • この問題を解決するには、バイナリ依存関係の一方を削除します。

クラスパス間の競合の修正

Gradle がコンパイル クラスパスを解決する際、まずランタイム クラスパスが解決され、その結果によりコンパイル クラスパスに追加する依存関係のバージョンが判定されます。つまり、ランタイム クラスパスにより、それ以降のクラスパスで同じ依存関係に必要なバージョン番号が決まります。

アプリのランタイム クラスパスは、アプリのテスト APK のランタイム クラスパスでの依存関係をマッチングする際に、Gradle が必要とするバージョン番号の決定にも関係します。クラスパスの階層関係を図 1 に示します。

図 1. 複数のクラスパスに登場する依存関係のバージョン番号は、この階層に基づいてマッチングされる必要があります。

たとえば、アプリに implementation 依存関係コンフィグレーションを使用するあるバージョンの依存関係が含まれており、ライブラリ モジュールに runtimeOnly コンフィグレーションを使用する別のバージョンの依存関係が含まれている場合、同じ依存関係の異なるバージョンが複数のクラスパスに登場する競合が発生することがあります。

Android Gradle プラグイン 3.3.0 以降では、ランタイム クラスパスとコンパイル クラスパスへの依存関係を解決する際に、その後の特定のバージョン競合を自動的に修正しようとします。たとえば、ランタイム クラスパスにライブラリ 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 を使用して、次の例のように依存関係の解決をクエリすることができます。

    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 {
                ...
            }
        }
    }