複数の APK をビルドする

注意: 2021 年 8 月以降、 App Bundle として公開する必要があります。アプリを Google Play に公開する場合は Android App Bundle をビルドしてアップロードする。日時 最適化された APK が自動的に生成、配信され、 プロビジョニングして、コードとリソースのみをダウンロードするように アプリを実行する必要があります複数の APK を公開すると、 AAB 形式に対応していないストアに公開することはできません。その場合、 各 APK を自分でビルド、署名、管理する必要があります。

ただし、1 つの APK ですべてのターゲット デバイスをサポートすることをおすすめします そうすると、ファイルが原因で、APK のサイズが非常に大きくなる可能性があります。 複数の をサポート 画面密度またはアプリケーション バイナリ インターフェース(ABI)。APK のサイズを小さくする 1 つの方法は、 複数の APK を使用して、 特定の画面密度や ABI に対応するファイルが含まれています。

Gradle では、各画面密度や ABI に固有のコードとリソースのみを含む APK を個別に作成できます。このページでは、複数の APK を生成するようにビルドを構成する方法について説明します。複数のバージョンのアプリを作成する必要がある場合 画面密度や ABI に基づかないアプリについては、代わりにビルド バリアントを使用してください。

複数の APK 用のビルドを構成する

複数の APK 用のビルドを構成するには、モジュール レベルの build.gradle ファイルに splits ブロックを追加します。対象 splits ブロック、指定 Gradle による生成方法を指定する density ブロック 密度ごとの APK、または Gradle の必要な動作を指定する abi ブロック を使用して ABI ごとの APK を生成できます。密度ブロックと ABI ブロックの両方を指定できます。 ビルドシステムは、画面密度と ABI の組み合わせごとに APK を作成します。

画面密度用の複数の APK の構成

画面密度ごとに異なる APK を作成するには、 density ブロック splits ブロック。density ブロックに、 必要な画面密度と互換性のある画面サイズのリスト。次のリストのみを使用してください。 必要な場合は、互換性のある画面サイズ <ph type="x-smartling-placeholder"></ph> 各 APK のマニフェスト内の <compatible-screens> 要素。

画面密度用の複数の APK を構成するには、以下の Gradle DSL オプションを使用します。

Groovy の場合は enable、Kotlin スクリプトの場合は isEnable
この要素を true に設定すると、Gradle で複数の APK が生成されます 画面密度に応じて決まりますデフォルト値は false
exclude
Gradle から除外する密度のカンマ区切りのリストを指定します 使用して個別の APK を生成できます。次の場合は exclude を使用 ほとんどの画面密度用の APK を生成したいが、少数の画面を除外する必要がある アプリがサポートしていない密度です。
reset()

画面密度のデフォルト リストをクリアします。以下と組み合わせる場合にのみ使用する: include 要素: 必要な密度を指定する 追加できます

次のスニペットでは、画面密度のリストに reset() を呼び出して ldpixxhdpi リストをクリアしてから、include を使用します。

reset()                  // Clears the default list from all densities
                         // to no densities.
include "ldpi", "xxhdpi" // Specifies the two densities to generate APKs
                         // for.
include
Gradle に生成させる密度のカンマ区切りのリストを指定します 。reset() と組み合わせて使用し、 密度のリストを返します。
compatibleScreens

互換性のある画面サイズのカンマ区切りのリストを指定します。これにより、 一致する マニフェスト内の <compatible-screens> ノードは、 必要があります。

この設定により、両方の画面を簡単に管理できるようになります。 密度と画面サイズを同じ build.gradle セクションに配置します。 ただし、 <compatible-screens> はデバイスの種類を制限できます 確認しましょうさまざまなユースケースをサポートする 詳しくは、 画面の互換性の概要をご覧ください。

画面密度に基づく各 APK には、 特定の制限が設定された <compatible-screens> タグ サポートする画面タイプ(複数の画面タイプを公開している場合でも) APK - 一部の新しいデバイスが複数の APK フィルタに一致しない。そのため Gradle は常にアセットを含む追加のユニバーサル APK を生成する サポートしており、すべての画面密度に対応しており、 <compatible-screens> タグ。これを公開 ユニバーサル APK と密度ごとの APK を組み合わせて、 APK と一致しないデバイスが <compatible-screens> タグ。

次の例では、アクティビティごとに個別の APK を生成します 画面 密度ldpixxhdpi、および xxxhdpi。これを行うには、exclude を使用して、 すべての画面密度のデフォルト リストから選択することもできます。

Groovy

android {
  ...
  splits {

    // Configures multiple APKs based on screen density.
    density {

      // Configures multiple APKs based on screen density.
      enable true

      // Specifies a list of screen densities you don't want Gradle to create multiple APKs for.
      exclude "ldpi", "xxhdpi", "xxxhdpi"

      // Specifies a list of compatible screen size settings for the manifest.
      compatibleScreens 'small', 'normal', 'large', 'xlarge'
    }
  }
}

Kotlin

android {
    ...
    splits {

        // Configures multiple APKs based on screen density.
        density {

            // Configures multiple APKs based on screen density.
            isEnable = true

            // Specifies a list of screen densities you don't want Gradle to create multiple APKs for.
            exclude("ldpi", "xxhdpi", "xxxhdpi")

            // Specifies a list of compatible screen size settings for the manifest.
            compatibleScreens("small", "normal", "large", "xlarge")
        }
    }
}

ビルドをカスタマイズする方法について詳しくは、 特定の画面タイプやデバイスに適用する場合は、 制限付きの宣言を宣言 画面サポートをご覧ください。

ABI 用の複数の APK の構成

ABI ごとに異なる APK を作成するには、splits ブロックの内側に abi ブロックを追加します。abi ブロックで、リソースのリストを指定します。 選択できます。

次の Gradle DSL オプションを使用して、アプリごとに複数の APK を設定します。 ABI:

Groovy の場合は enable、Kotlin スクリプトの場合は isEnable
この要素を true に設定すると、Gradle で複数の 定義した ABI に基づく APK。デフォルト値は false です。
exclude
Gradle に実行させない ABI のカンマ区切りのリストを指定します 別の APK を生成できます。次のトークンを生成する場合は、exclude を使用します。 ほとんどの ABI 用の APK(ただし、アプリで除外する一部の ABI を除外する必要がある) サポート。
reset()

ABI のデフォルト リストを消去します。以下と組み合わせる場合にのみ使用する: include 要素で、追加する ABI を指定します。

次のスニペットでは、ABI のリストが x86 のみに設定され、 reset() を呼び出してリストを消去し、x86_64 次に include を使用します。

reset()                 // Clears the default list from all ABIs to no ABIs.
include "x86", "x86_64" // Specifies the two ABIs we want to generate APKs for.
include
Gradle で APK を生成する ABI のカンマ区切りのリストを指定します できます。reset() と組み合わせて使用し、 ABI のリストを返します
Groovy の場合は universalApk、Groovy の場合は isUniversalApk Kotlin スクリプト

true の場合、Gradle はさらにユニバーサル APK を生成します ABI ごとの APK。ユニバーサル APK には、すべての ABI のコードとリソースが 最適です。デフォルト値は false です。

このオプションは splits.abi ブロックで使用できます。複数の APK をビルドする場合 Gradle は常に画面密度に基づいて、ユニバーサル APK を生成します。 には、あらゆる画面密度に対応するコードとリソースが含まれています。

次の例では、各 ABI(x86x86_64)用の APK を個別に生成しています。これを行うには、reset() を使用します。 は、ABI の空のリストから開始し、include それぞれが APK を取得する ABI のリスト。

Groovy

android {
  ...
  splits {

    // Configures multiple APKs based on ABI.
    abi {

      // Enables building multiple APKs per ABI.
      enable true

      // By default all ABIs are included, so use reset() and include to specify that you only
      // want APKs for x86 and x86_64.

      // Resets the list of ABIs for Gradle to create APKs for to none.
      reset()

      // Specifies a list of ABIs for Gradle to create APKs for.
      include "x86", "x86_64"

      // Specifies that you don't want to also generate a universal APK that includes all ABIs.
      universalApk false
    }
  }
}

Kotlin

android {
  ...
  splits {

    // Configures multiple APKs based on ABI.
    abi {

      // Enables building multiple APKs per ABI.
      isEnable = true

      // By default all ABIs are included, so use reset() and include to specify that you only
      // want APKs for x86 and x86_64.

      // Resets the list of ABIs for Gradle to create APKs for to none.
      reset()

      // Specifies a list of ABIs for Gradle to create APKs for.
      include("x86", "x86_64")

      // Specifies that you don't want to also generate a universal APK that includes all ABIs.
      isUniversalApk = false
    }
  }
}

サポートされている ABI のリストについては、以下をご覧ください。 サポート対象 ABI

ネイティブ / C++ コードを含まないプロジェクト

ネイティブ/C++ コードのないプロジェクトの場合、[Build Variants] パネルには 2 つの 列: モジュールActive Build バリアントのバリアントを作成します。

[ビルド バリアント] パネル
図 1. [Build Variants] パネルには、 C++ コードをサポートしています。

そのプロジェクトの Active Build Variant 値 module は、デプロイされてエディタに表示されるビルド バリアントを指定します。 バリアントを切り替えるには、モジュールの [Active Build Variant] セルをクリック 目的のバリエーションをリストから選択します。

ネイティブ / C++ コードを含むプロジェクト

ネイティブ/C++ コードを含むプロジェクトの場合、[Build Variants] パネルには 3 つの 列: モジュールActive Build バリアントアクティブ ABI があります(図 2 を参照)。

図 2. [Build Variants] パネルに以下の [Active ABI] 列が追加されます。 ネイティブ/C++ コードを使用して開発できます。

モジュールの [Active Build Variant] 値 は、デプロイされてエディタに表示されるビルド バリアントを決定します。 ネイティブ モジュールの場合、[Active ABI] 値によってエディタが処理する ABI が決まります。 デプロイされるリソースには影響しません。

ビルドタイプまたは ABI を変更するには:

  1. [Active Build Variant] のセルをクリックします。 または [Active ABI] 列を選択します。
  2. リストから目的のバリアントまたは ABI を選択する 表示されます。新しい同期が自動的に実行されます。

アプリまたはライブラリ モジュールのいずれかの列を変更すると、すべての列に変更が適用される 作成されます。

バージョン管理の構成

Gradle が複数の APK を生成する場合、デフォルトでは、各 APK に同じものが バージョン情報(モジュール レベルで指定されるもの) build.gradle または build.gradle.kts ファイル。これは、 Google Play ストアでは、同じアプリに すべての APK に固有のバージョン情報を <ph type="x-smartling-placeholder"></ph> versionCode。Google Play ストアにアップロードする前にご確認ください。

モジュール レベルの build.gradle ファイルは次のように構成できます。 各 APK の versionCode をオーバーライドできます。マッピングを作成することで 設定する ABI と密度ごとに一意の数値を割り当てます。 出力バージョン コードをオーバーライドして、出力値を defaultConfig で定義されたバージョン コードを結合するか、 割り当てられている数値を含む productFlavors ブロック 密度(ABI)です。

次の例では、x86 ABI の APK が versionCode が 2004 で、x86_64 ABI が取得されます。 versionCode は 3004 になります。

大きな値(1,000 など)でバージョン コードを割り当てると、 アプリをアップデートする必要が生じた場合に、後で一意のバージョン コードを割り当てることができます。対象 たとえば、defaultConfig.versionCode が 5 秒で 5 になるまで反復処理を行う場合、 その後のアップデートで、Gradle は 2005 の versionCodex86 APK と 3005 を x86_64 APK に追加します。

ヒント: ビルドにユニバーサル APK が含まれている場合は、 他のどの APK よりも低い versionCode。 Google Play ストアは、対象デバイスと互換性があり、versionCode が最も大きいアプリのバージョンをインストールするため、小さい versionCode をユニバーサル APK に割り当てることで、Google Play ストアでユニバーサル APK にフォールバックする前に、いずれかの APK がインストールされるようになります。次のサンプルコード これに対処するために、ユニバーサル APK の デフォルトは versionCode です。

Groovy

android {
  ...
  defaultConfig {
    ...
    versionCode 4
  }
  splits {
    ...
  }
}

// Map for the version code that gives each ABI a value.
ext.abiCodes = ['armeabi-v7a':1, x86:2, x86_64:3]

// For per-density APKs, create a similar map:
// ext.densityCodes = ['mdpi': 1, 'hdpi': 2, 'xhdpi': 3]

import com.android.build.OutputFile

// For each APK output variant, override versionCode with a combination of
// ext.abiCodes * 1000 + variant.versionCode. In this example, variant.versionCode
// is equal to defaultConfig.versionCode. If you configure product flavors that
// define their own versionCode, variant.versionCode uses that value instead.
android.applicationVariants.all { variant ->

  // Assigns a different version code for each output APK
  // other than the universal APK.
  variant.outputs.each { output ->

    // Stores the value of ext.abiCodes that is associated with the ABI for this variant.
    def baseAbiVersionCode =
            // Determines the ABI for this variant and returns the mapped value.
            project.ext.abiCodes.get(output.getFilter(OutputFile.ABI))

    // Because abiCodes.get() returns null for ABIs that are not mapped by ext.abiCodes,
    // the following code doesn't override the version code for universal APKs.
    // However, because you want universal APKs to have the lowest version code,
    // this outcome is desirable.
    if (baseAbiVersionCode != null) {

      // Assigns the new version code to versionCodeOverride, which changes the
      // version code for only the output APK, not for the variant itself. Skipping
      // this step causes Gradle to use the value of variant.versionCode for the APK.
      output.versionCodeOverride =
              baseAbiVersionCode * 1000 + variant.versionCode
    }
  }
}

Kotlin

android {
  ...
  defaultConfig {
    ...
    versionCode = 4
  }
  splits {
    ...
  }
}

// Map for the version code that gives each ABI a value.
val abiCodes = mapOf("armeabi-v7a" to 1, "x86" to 2, "x86_64" to 3)

// For per-density APKs, create a similar map:
// val densityCodes = mapOf("mdpi" to 1, "hdpi" to 2, "xhdpi" to 3)

import com.android.build.api.variant.FilterConfiguration.FilterType.*

// For each APK output variant, override versionCode with a combination of
// abiCodes * 1000 + variant.versionCode. In this example, variant.versionCode
// is equal to defaultConfig.versionCode. If you configure product flavors that
// define their own versionCode, variant.versionCode uses that value instead.
androidComponents {
    onVariants { variant ->

        // Assigns a different version code for each output APK
        // other than the universal APK.
        variant.outputs.forEach { output ->
            val name = output.filters.find { it.filterType == ABI }?.identifier

            // Stores the value of abiCodes that is associated with the ABI for this variant.
            val baseAbiCode = abiCodes[name]
            // Because abiCodes.get() returns null for ABIs that are not mapped by ext.abiCodes,
            // the following code doesn't override the version code for universal APKs.
            // However, because you want universal APKs to have the lowest version code,
            // this outcome is desirable.
            if (baseAbiCode != null) {
                // Assigns the new version code to output.versionCode, which changes the version code
                // for only the output APK, not for the variant itself.
                output.versionCode.set(baseAbiCode * 1000 + (output.versionCode.get() ?: 0))
            }
        }
    }
}

別のバージョン コード スキームの例については、バージョン コードの割り当てをご覧ください。

複数の APK をビルドする

モジュール レベルの build.gradle または build.gradle.kts ファイルを選択して複数の APK をビルドするには、 構築 >[Build APK] を選択して、現在の [Project] ペインで選択したモジュールを確認します。Gradle が APK を作成する プロジェクトの build/outputs/apk/ 内の密度または ABI ごとに されます。

Gradle は、複数の APK を構成した画面密度または ABI ごとに APK をビルドします。 密度と ABI の両方で複数の APK を有効にすると、Gradle で APK が作成されます 画面表示と ABI の組み合わせごとに表示されます。

たとえば、次のようになります。 build.gradle スニペットを使用すると、mdpihdpi 密度、x86 ABI、x86_64 ABI:

Groovy

...
  splits {
    density {
      enable true
      reset()
      include "mdpi", "hdpi"
    }
    abi {
      enable true
      reset()
      include "x86", "x86_64"
    }
  }

Kotlin

...
  splits {
    density {
      isEnable = true
      reset()
      include("mdpi", "hdpi")
    }
    abi {
      isEnable = true
      reset()
      include("x86", "x86_64")
    }
  }

この例の構成の出力には、以下の 4 つの APK が含まれます。

  • app-hdpiX86-release.apk: 以下に関するコードとリソースが含まれます。 hdpi 密度と x86 ABI。
  • app-hdpiX86_64-release.apk: 以下に関するコードとリソースが含まれます。 hdpi 密度と x86_64 ABI。
  • app-mdpiX86-release.apk: 以下に関するコードとリソースが含まれます。 mdpi 密度と x86 ABI。
  • app-mdpiX86_64-release.apk: 以下に関するコードとリソースが含まれます。 mdpi 密度と x86_64 ABI。

画面密度に基づいて複数の APK をビルドする場合、Gradle では常に、画面密度ごとの APK に加え、すべての画面密度用のコードとリソースを含むユニバーサル APK が生成されます。

アプリの依存関係に基づいて複数の APK を ABI によって、Gradle はすべての universalApk true を指定する場合の ABI build.gradle ファイル内の splits.abi ブロック (Groovy の場合)または isUniversalApk = truebuild.gradle.kts ファイルの splits.abi ブロック (Kotlin スクリプトの場合)。

APK ファイル名の形式

複数の APK をビルドする場合、Gradle は次の要素を使用して APK ファイル名を生成します scheme:

modulename-screendensityABI-buildvariant.apk

スキームのコンポーネントは次のとおりです。

modulename
ビルド対象のモジュール名を指定します。
screendensity
画面密度用の APK が複数有効になっている場合に、画面を指定する APK の密度(mdpi など)。
ABI

ABI 用の複数の APK が有効になっている場合、 x86 として指定します。

画面密度と ABI の両方の APK が複数有効になっている場合、 Gradle は密度名と ABI 名を連結します。次に例を示します。 mdpiX86。ABI ごとに universalApk が有効になっている場合 APK、Gradle でユニバーサル APK の ABI 部分として universal を使用 あります。

buildvariant
ビルドするビルド バリアントを指定します(debug など)。

たとえば、mdpi 画面密度 APK を myApp のデバッグ バージョンの場合、APK のファイル名は myApp-mdpi-debug.apk。リリース 複数の APK をビルドするように構成されている mdpi 画面密度と x86 ABI の APK ファイル名は次のようになります。 myApp-mdpiX86-release.apk