ビルドの依存関係の追加

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 ライブラリ モジュール への依存関係を宣言します(この名前は、include: settings.gradle ファイル内)で定義されたライブラリ名と一致している必要があります)。 アプリのビルド時に、ビルドシステムはライブラリ モジュールをコンパイルし、コンパイルした結果を 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 プラグインは依存関係をアノテーション プロセッサであると見なします。 プラグインがコンパイル クラスパスでアノテーション プロセッサを検出すると、ビルドエラーが生成されます。

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

たとえば、"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 ブロックを使用します。 たとえば、キー値ペアとしてプリミティブ データ型を渡す場合、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 リポジトリ インデックスで確認できます(以下のプログラムからのアクセスをご覧ください)。

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

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_C および LIB_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 タスクが提供されています。

このタスクを実行するには、次の手順に従います。

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

次のサンプル出力はデバッグ ビルド バリアントの依存関係ツリーを示しており、この出力には、前の例のローカル ライブラリ モジュールの依存関係とリモートの依存関係が含まれています。

Executing tasks: [androidDependencies]
:app:androidDependencies
debug
/**
 * Both the library module dependency and remote binary dependency are listed
 * with their transitive dependencies.
 */
+--- MyApp:mylibrary:unspecified
|    \--- com.android.support:appcompat-v7:28.0.0
|         +--- com.android.support:animated-vector-drawable:28.0.0
|         |    \--- com.android.support:support-vector-drawable:28.0.0
|         |         \--- com.android.support:support-v4:28.0.0
|         |              \--- LOCAL: internal_impl-28.0.0.jar
|         +--- com.android.support:support-v4:28.0.0
|         |    \--- LOCAL: internal_impl-28.0.0.jar
|         \--- com.android.support:support-vector-drawable:28.0.0
|              \--- com.android.support:support-v4:28.0.0
|                   \--- LOCAL: internal_impl-28.0.0.jar
\--- com.android.support:appcompat-v7:28.0.0
     +--- com.android.support:animated-vector-drawable:28.0.0
     |    \--- com.android.support:support-vector-drawable:28.0.0
     |         \--- com.android.support:support-v4:28.0.0
     |              \--- LOCAL: internal_impl-28.0.0.jar
     +--- com.android.support:support-v4:28.0.0
     |    \--- LOCAL: internal_impl-28.0.0.jar
     \--- com.android.support:support-vector-drawable:28.0.0
          \--- com.android.support:support-v4:28.0.0
               \--- LOCAL: internal_impl-28.0.0.jar
...

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

同じ依存関係のバージョンが複数のクラスパスに登場し、それらが競合する場合、次のようなエラーが表示されます。

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.

たとえば、アプリが implementation 依存関係コンフィグレーションを使用するバージョンの依存関係を使用し、ライブラリ モジュールが runtimeOnly コンフィグレーションを使用して異なるバージョンの依存関係を含んでいる場合に、このような競合が発生することがあります。 この問題を解決するには、以下のいずれかを実行します。

  • 必要なバージョンの依存関係を api 依存関係としてライブラリ モジュールに含めます。 これにより、ライブラリ モジュールでは依存関係を宣言するだけになりますが、アプリ モジュールはその API に推移的にアクセスします。
  • または、両方のモジュールに依存関係を宣言します。この場合、各モジュールが同じバージョンの依存関係を使用する必要があります。 プロジェクト全体のプロパティ設定を行うことを考えて、プロジェクト全体で依存関係のバージョンが一致するようにしてください。

カスタムビルド ロジックの適用

このセクションでは、Android Gradle プラグインの拡張や独自のプラグインの作成に役立つトピックについて詳しく説明します。

カスタム ロジックへのバリアント依存関係の公開

ライブラリに、他のプロジェクトまたはサブプロジェクトで使用したい機能が含まれていることがあります。 ライブラリの公開とは、ライブラリが他で使用できるようにするためのプロセスです。 ライブラリは、コンパイル時および実行時にアクセスできる依存関係を制御できます。

各クラスパスの推移的な依存関係を保持するために、2 つの異なるコンフィグレーションを使用します。これらはライブラリの利用元により、以下のようにして使用される必要があります。

  • variant_nameApiElements:このコンフィグレーションは、コンパイル時に使用できる推移的な依存関係を保持します。
  • variant_nameRuntimeElements:このコンフィグレーションは、実行時に使用できる推移的な依存関係を保持します。

異なるコンフィグレーションの関係について詳しくは、Java ライブラリ プラグイン コンフィグレーションをご覧ください。

カスタム依存関係の解決方針

プロジェクトに同じライブラリだがバージョンが異なる 2 つの依存関係がある場合、依存関係の競合が発生することがあります。 たとえば、プロジェクトがバージョン 1 のモジュール A と、バージョン 2 のモジュール B に依存し、モジュール 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 {
            ...
        }
    }
}