パブリケーション バリアントを設定する

パブリケーション バリアントを使用すると、高度にカスタマイズされたエクスペリエンスをユーザーに提供できます。パブリケーション バリアントを構成することにより、それぞれが固有の属性を持つさまざまなビルド バリアントを公開できます。

ライブラリの複数のビルド バリアントを公開すると、ユーザーはニーズに合わせて適切な機能を選択できます。たとえば、debug ビルドタイプと release ビルドタイプについて、それぞれ異なるアーティファクトを公開できます。debug パブリケーション アーティファクトには、追加のロギングコードと、この追加ロギングを有効にするためのさまざまな依存関係を含めることができます。

先に進む前に、ライブラリをリリースする準備を完了してください。

Gradle Module Metadata を使用する

ライブラリのバリアントを公開するには、Gradle Module Metadata(GMM) を使用する必要があります。GMM はパブリケーションを記述したものであり、バリアント識別による依存関係の管理を行います。GMM は、デフォルトでライブラリとともに公開されています。

GMM を使用すると、次のようなメリットがあります。

  • Gradle 6.0 以降で GMM を使用する場合、それぞれが固有の属性と依存関係を持つ複数のパブリケーション バリアント(つまり複数のアーティファクト)を公開できます。GMM の代わりに Maven の POM ファイルを使用する場合、公開できるアーティファクトは 1 つだけです。POM ファイルを使用する場合は、分類器を使用して追加のアーティファクトを公開できますが、追加のアーティファクトに固有の依存関係を含めることはできません。
  • Gradle は、それぞれが固有の依存関係を持つコンパイル用のバリアントとランタイム用のバリアントを 1 つずつ自動で作成します。コンパイル用とランタイム用にバリアントを 1 つずつ公開できるので、コンシューマーはいつライブラリを使用するかに応じてバリアントを選択できます。GMM は、公開ライブラリによる apiimplementationcompileOnly/runtimeOnly の使用に基づいて、コンシューマーがコンパイル用とランタイム用のさまざまな依存関係を確認できます。依存関係の完全なリストについては、依存関係コンフィグレーションをご覧ください。これは、単一のパブリケーション バリアントを公開する場合にも利用できます。
  • テスト フィクスチャを使用する場合は、コンシューマーがフィクスチャを選択できる特別なメタデータ(ケーパビリティ)を持つ追加のバリアントを公開できます。これは、単一のパブリケーション バリアントを公開する場合にも利用できます。

パブリケーション バリアントを理解する

パブリケーション バリアントの仕組みを理解するには、Gradle の基本的な公開手順を知っていると役立ちます。パブリケーションの主要なコンセプトは次のとおりです。

  • ビルド バリアント: Gradle がライブラリをビルドするために使用する構成。ビルドタイプとプロダクト フレーバーの組み合わせです。詳しくは、Android ビルドの用語集をご覧ください。
  • アーティファクト: ビルドによって生成されるファイルまたはディレクトリ。ライブラリ公開の文脈では、一般的にアーティファクトは JAR ファイルまたは AAR ファイルです。
  • パブリケーション バリアント: 関連する属性、機能、依存関係を含むアーティファクト。なお、Gradle では、パブリケーション バリアントを「バリアント」と呼びます。しかし、このドキュメントでは、「ビルド バリアント」と区別するために「パブリケーション バリアント」と呼びます。
  • 属性: 複数のオプションがある場合、Gradle は属性を使用してパブリケーション バリアントの識別と選択を行います。たとえば、org.gradle.usage=java-apiorg.gradle.jvm.version=11 は、バリアントの属性です。
  • ソフトウェア コンポーネント: 1 つ以上のパブリケーション バリアントを保持することができ、単一の Maven 座標セット(groupdId:artifactId:version)に公開される Gradle オブジェクト。Project.getComponents() を介して Gradle の DSL で開示されます。
  • パブリケーション: リポジトリに公開され、コンシューマーによって使用されるもの。パブリケーションは、単一のソフトウェア コンポーネントとそのメタデータで構成されます。メタデータには、たとえば ID があります(groupId:artifactId:version)。

Android Gradle プラグイン(AGP)7.1 でドメイン固有の言語(DSL)が導入され、公開時に使用されるビルド バリアントと無視されるビルド バリアントを管理できるようになりました。DSL を使用すると、次のいずれかを含む SoftwareComponent のインスタンスを作成できます。

  • 単一のビルド バリアントに由来する単一のパブリケーション バリアント。
  • 複数のビルド バリアントに由来する複数のパブリケーション バリアント。

複数のパブリケーション バリアントを持つソフトウェア コンポーネントを作成する場合、AGP はバリアントごとに属性を設定して、コンシューマーが必要なバリアントを適切に選択できるようにします。これらの属性は、ビルド バリアントの作成に使用されるビルドタイプとフレーバーから直接生成されます。単一のパブリケーション バリアントを持つコンポーネントを作成する場合は、区別する必要がないため属性は不要です。

単一のパブリケーション バリアントを持つソフトウェア コンポーネントを作成する

以下のスニペットは、release ビルド バリアントから作成される単一のパブリケーション バリアントを持つソフトウェア コンポーネントを構成し、ソース JAR をセカンダリ アーティファクトとして追加します。

Kotlin

android {
  publishing {
    singleVariant("release") {
        withSourcesJar()
    }
  }
}

Groovy

android {
  publishing {
    singleVariant('release') {
        withSourcesJar()
    }
  }
}

それぞれが単一のパブリケーション バリアントを持つ複数のコンポーネントを作成し、異なる Maven 座標でそれらを配布することができます。この場合、パブリケーション バリアントに属性は設定されません。したがって、このパブリケーション バリアントが release ビルド バリアントに由来するかどうかをパブリケーションのメタデータから判断することはできません。パブリケーション バリアントが 1 つしかないので、曖昧さ回避は不要です。

複数のパブリケーション バリアントを持つソフトウェア コンポーネントを作成する

ビルド バリアントの全部または一部を選択して、単一のソフトウェア コンポーネントに含めることができます。AGP は、ビルドタイプ名、プロダクト フレーバー名、プロダクト フレーバー ディメンション名を使用して自動的に属性を作成し、消費元のプロジェクトがそれらを区別できるようにします。

すべてのビルド バリアントを単一のコンポーネントで公開するには、モジュール レベルの build.gradle ファイルの multipleVariants{} ブロックで allVariants() を指定します。

Kotlin

android {
  publishing {
    multipleVariants {
      allVariants()
      withJavadocJar()
    }
  }
}

Groovy

android {
  publishing {
    multipleVariants {
      allVariants()
      withJavadocJar()
    }
  }
}

これにより、default という名前の単一のコンポーネントが作成されます。このコンポーネントに別の名前を付けるには、multipleVariants({name}) を使用します。この場合、すべてのビルドタイプとプロダクト フレーバー ディメンションが属性として使用されます。

includeBuildTypeValues()includeFlavorDimensionAndValues() を使用して、どのバリアントを公開するかを選択することもできます。

Kotlin

android {
  publishing {
    multipleVariants("custom") {
      includeBuildTypeValues("debug", "release")
      includeFlavorDimensionAndValues(
        dimension = "color",
        values = arrayOf("blue", "pink")
      )
        includeFlavorDimensionAndValues(
          dimension = "shape",
          values = arrayOf("square")
      )
    }
  }
}

Groovy

android {
  publishing {
    multipleVariants('custom') {
      includeBuildTypeValues('debug', 'release')
      includeFlavorDimensionAndValues(
        /*dimension =*/ 'color',
        /*values =*/ 'blue', 'pink'
      )
      includeFlavorDimensionAndValues(
        /*dimension =*/ 'shape',
        /*values =*/ 'square'
      )
    }
  }
}

この例のカスタム コンポーネントには、ビルドタイプ(debugrelease)、color ディメンション(bluepink)および shape ディメンション(square)のすべての組み合わせが含まれています。

1 つのディメンションから 1 つの値のみを公開する場合でも、AGP がすべてのディメンションでどの値を使用するかを認識できるように、すべてのフレーバー ディメンションをリストする必要があります。

生成されるパブリケーション バリアントとそれらに関連付する属性を次の表に示します。

バリアント 属性
blueSquareDebug com.android.build.api.attributes.BuildTypeAttr="debug" com.android.build.api.attributes.ProductFlavorAttr:color="blue"
blueSquareRelease com.android.build.api.attributes.BuildTypeAttr="release"
com.android.build.api.attributes.ProductFlavorAttr:color="blue"
pinkSquareDebug com.android.build.api.attributes.BuildTypeAttr="debug"
com.android.build.api.attributes.ProductFlavorAttr:color="pink"
pinkSquareRelease com.android.build.api.attributes.BuildTypeAttr="release"
com.android.build.api.attributes.ProductFlavorAttr:color="pink"

実際には、もっと多くのバリアントが公開されます。たとえば、上記のバリアントはそれぞれ 2 回ずつ公開されます。1 回はコンパイル用、もう 1 回はランタイム用で、それぞれ依存関係が異なります(宣言された依存関係が implementationapi のどちらを使用しているかによります)。また、属性 org.gradle.Usage の値も異なります。ただし、この 2 つのバリアントのアーティファクト(AAR ファイル)は同じになります。

詳しくは、publishing API のドキュメントをご覧ください。

マルチフレーバー ライブラリの公開に関する互換性の問題

AGP 7.0 以前を使用するプロジェクトでは、AGP 7.1 以降で公開されたマルチフレーバー ライブラリを使用できません。これは AGP 7.1 でプロダクト フレーバー ディメンションの属性名を dimensionName から com.android.build.api.attributes.ProductFlavor:dimensionName に変更したことによる既知の問題です。プロジェクトの設定によっては、古いバリアント API の missingDimensionStrategy を使用してこの問題を回避できます。

たとえば、次のようなアプリ プロジェクトにバージョンのプロダクト フレーバー ディメンションのみがあるとします。

Kotlin

android {
    applicationVariants.forEach { variant ->
        val flavor = variant.productFlavors[0].name
        val attributePrefix = "com.android.build.api.attributes.ProductFlavor"
        val dimensionName = "version"
        variant.missingDimensionStrategy("$attributePrefix:$dimensionName", flavor)
    }
}

Groovy

android {
    applicationVariants.forEach { variant ->
        def flavor = variant.getProductFlavors()[0].name
        def attributePrefix = "com.android.build.api.attributes.ProductFlavor"
        def dimensionName = "version"
        variant.missingDimensionStrategy("$attributePrefix:$dimensionName", flavor)
    }
}