一つのAPK だけで可能な限り全ての対象端末をサポートする必要がありますが、 それだと複数の 画面密度や Application Binary Interfaces (ABIs)をサポートするためのファイルが必要なため、 APK のサイズが非常に大きくなってしまいます。 APK のサイズを減らす一つの方法は、特定の画面密度やABI用のファイルを含んだ複数のAPKを作成することです。
Gradle はAPK スプリット を使って、各画面密度やABI固有のコードやリソースのみを含んだ個別のAPKを作成します。 画面密度やABIに基づかずに異なるバージョンのアプリを作成する必要がある場合は、APK スプリットではなくビルドバリアントを使用できます。
APK スプリットを有効にするには、 モジュールレベルのbuild.gradle
ファイルに
splits {}
ブロックを追加します。
splits {}
ブロック内では、Gradle が画面密度ごとのAPKをどのように生成するかを指定する density {}
ブロックや、
Gradle がABI ごとのAPKをどのように生成するかを指定する abi {}
ブロックを設定します。
density ブロックとABI ブロックは両方設定することもでき、ビルドシステムは各画面密度とABIの組み合わせごとにスプリットAPKを作成します。
異なる画面密度ごとに別々の APK を作成するには、
splits {}
ブロック内にdensity {}
ブロックを追加します。
density {}
ブロック内では、希望する画面密度およびそれと互換性のあるスクリーンサイズの一覧を設定します。
互換スクリーンサイズの一覧は、各APKのマニフェストで
<compatible-screens>
要素を設定する必要がある場合のみ使用されます。
画面密度ごとの APK スプリットを設定するには、以下のGradle DSLオプションを使います:
enable
true
を設定した場合、Gradle はあなたが定義した画面密度に基づいてAPK スプリットを生成します。既定値は false
です。
exclude
exclude
を使用してアプリでサポートしていない画面密度を除外する必要があります。
reset()
include
要素も一緒に使って追加したい画面密度を設定する必要があります。
以下のコードでは、reset()
を呼び出して一覧をクリアした後に include
を使用することで、
画像密度一覧にldpi
とxxhdpi
のみを設定しています。:
reset() // clear the default list from all densities to no densities include "ldpi", "xxhdpi" // specify the two densities we want to generate APKs for
include
reset()
も一緒に使って、画面密度の一覧を正確に指定してください。
compatibleScreens
<compatible-screens>
ノードを挿入します。
このオプション設定によって、同一 build.gradle
上で画面密度と画面サイズの両方を簡単に管理できます。
しかし、 <compatible-screens>
を使用するとアプリが動作する端末のタイプが制限されます。
異なる画面サイズをサポートする他の方法については、Support Multiple Screensを参照してください。
<compatible-screens>
タグを使うとAPK がサポートする画面タイプに制限が出て来ます。
画面密度に基づいたAPKスプリットはその<compatible-screens>
タグを含むため、
複数のAPKを公開したとしても、いくつかの新しい端末では条件に合致するAPKが無いということがあります。
そのためGradle は常に、全ての画面密度に対応した素材を含んで
<compatible-screens>
タグを使用しないユニバーサルAPKを追加で生成します。
このユニバーサルAPKとスプリットAPKを合わせて配信し、スプリットAPKの
<compatible-screens>
タグと合致しない端末はユニバーサルAPKに切り替えられるようにする必要があります。
以下の例では、サポートしている画面の範囲内でldpi
, xxhdpi
,xxxhdpi
を除いた各画面密度用の個別APKを生成します。
これは、 exclude
を使って既定の全画面密度一覧から三つの画面密度を削除することで行っています。:
android { ... splits { // Configures screen density split settings density { // Enables density APK splits enable true // Specifies a list of screen densities Gradle should not create APK splits for exclude "ldpi", "xxhdpi", "xxxhdpi" // Specifies a list of compatible screen size settings for the manifest compatibleScreens 'small', 'normal', 'large', 'xlarge' } } }
画面密度名と画面サイズ名の一覧については、複数の画面をサポートする方法を参照してください。 特定の画面タイプと端末向けにアプリを配布する詳細については、Distributing to Specific Screensを参照してください。
異なるABIごとに別個のAPKを作成するには、
splits {}
ブロック内にabi {}ブロックを追加します。 abi {} ブロック内では、希望するABIの一覧を設定します。
ABIごとの APK スプリットを設定するには、以下のGradle DSLオプションを使います。:
enable
true
を設定した場合、Gradle はあなたが定義したABIに基づいてAPK スプリットを生成します。既定値は false
です。
exclude
exclude
を使用してアプリでサポートしていないABIを除外する必要があります。
reset()
include
要素も一緒に使って追加したいABIを設定する必要があります。 以下のコードでは、reset()
を呼び出して一覧をクリアした後にinclude
を使用することで、ABI一覧に x86
と mips
のみを設定しています。:
reset() // clear the default list from all ABIs to no ABIs include "x86", "mips" // specify the two ABIs we want to generate APKs for
include
reset()
も一緒に使って、ABIの一覧を正確に指定してください。
universalApk
true
を設定した場合、スプリットAPKに加えてユニバーサル APKも作成します。
ユニバーサルAPK は一つのAPK内に全てのABI用のコードとリソースが含まれています。
既定値は false
です。
このオプションはABI ごとのAPK スプリットでのみ使用できるので注意してください。
画面密度のAPKスプリットの場合は、全ての画面密度用のコードとリソースを含んだユニバーサルAPKを常に生成します。
以下の例では、x86
, armeabi-v7a
, and mips
の各ABI用の個別APKを生成します。
これは、reset()
を使ってABI一覧を空にし、その後でAPKを取得するABI三つの一覧を include
することで行います。:
android { ... splits { // Configures screen ABI split settings abi { // Enable ABI APK splits enable true // By default all ABIs are included, so use reset() and include to specify that we only // want APKs for x86, armeabi-v7a, and mips // Resets the list of ABIs that Gradle should create APKs for to none reset() // Specifies a list of ABIs that Gradle should create APKs for include "x86", "armeabi-v7a", "mips" // Specify that we do not want to also generate a universal APK that includes all ABIs universalApk false } } }
サポートされているABIの一覧については、サポートしている ABIを参照してください。
既定では、Gradle がAPK スプリットを生成した時、各APKはモジュールレベルの build.gradle
ファイルで指定されているものと同じバージョン情報を持ちます。
Google Play ストアでは同じバージョン情報を持つ同じアプリのAPKを複数公開することはできないので、
Play ストアにアップロードする前に各スプリットAPKに重複のない独自のversionCode
を持たせるようしてください。
モジュールレベルのbuild.gradle
ファイルを設定して、全てのスプリットAPKごとにversionCode
を上書きすることができます。
APKスプリットで使用される各ABIと画面密度に重複のない数値を割り当て、defaultConfig.versionCode
と画面密度やABIに割り当てられた数値を組み合わせた値で
出力されるバージョンコードを上書きします。
以下の例では、APK スプリットで使用される各ABI に重複のない数値を割り当てるための紐付け処理を作成しています。
この紐付け処理を使うと、ABI 値とdefaultConfig.versionCode
の値を紐付けしてスプリットごとのAPK バージョンコードが作成されます。
この例では、 x86
ABI 用のスプリットAPKのversionCode
は304となります。
defaultConfig.versionCode
が 5の場合、 Gradle は x86
スプリット APKのversionCode
に305 を割り当てます。
android { ... defaultConfig { ... versionCode 4 } splits { ... } } // map for the version code that gives each ABI a value ext.versionCodes = ['armeabi-v7a':1, mips:2, x86:3] // For each APK output variant, override versionCode with a combination of // ABI APK value * 100 + defaultConfig.versionCode android.applicationVariants.all { variant -> // assign different version code for each output variant.outputs.each { output -> output.versionCodeOverride = project.versionCodes.get(output.getFilter(OutputFile.ABI)) * 100 + android.defaultConfig.versionCode } }
これ以外のバージョンコード管理例の詳細については、 バージョンコードの割り当てを参照してください。
APK スプリットをビルドするためのモジュールレベル build.gradle
ファイルが設定できたら、
build.gradle
の順にクリックして、Project パネルで現在選択されている全てのモジュールのAPKをビルドします。
Gradle は各画面密度やABIごとのAPKをプロジェクトのbuild/outputs/apk/
ディレクトリに作成します。
Gradle は設定された画面密度やABIの各スプリットごとにAPKを作成します。
画面密度とABI両方のスプリットを有効にした場合、Gradle は各画面密度とABIの組み合わせごとにAPKを作成します。
例えば、以下のbuild.gradle
では密度mdpi と密度hdpi のAPKスプリット、およびABI x86とABI mipsのAPKスプリットのビルドを有効にしています。:
... splits { density { enable true reset() include "mdpi", "hdpi" } abi { enable true reset() include "x86", "mips" } }
上記設定例の場合だと以下四つのスプリットAPKが出力されます:
app-hdpiX86-release.apk
: hdpi 密度と x86 ABI のみのコードとリソースを内包している。app-hdpiMips-release.apk
: hdpi 密度と mips ABI のみのコードとリソースを内包している。app-mdpiX86-release.apk
: mdpi 密度と x86 ABI のみのコードとリソースを内包している。app-mdpiMips-release.apk
: mdpi 密度と mips ABI のみのコードとリソースを内包している。
APKスプリットをどのように設定したかに応じて、Gradle は全ての画面密度やABI用のコードとリソースを含んだユニバーサルAPKも生成します。
画面密度APKスプリットの場合、Gradle は密度ごとのAPKに加えて、全ての画面密度用のコードとリソースを含んだユニバーサルAPKを常に生成します。
ABI スプリットの場合、 build.gradle
ファイルの splits {}
ブロックのabi
項目内にuniversalApk true
を設定したのであれば、
全てのABI用のコードとリソースを含んだAPKを生成します。
APK スプリットを生成する場合、 Gradle は以下のような形式を使ってAPKのファイル名を決めます:
modulename-screendensityABI-buildvariant.apk
このスキームのコンポーネントは以下の通りです:
modulename
screendensity
ABI
universalApk
が有効になっている場合、
Gradle はユニバーサルAPKファイル名のABI 部分に"universal"を設定します。
buildvariant
例えば、画面密度mdpiが有効になったAPK スプリットを含んだ "myApp" のデバッグビルドでは、APKのファイル名はmyApp-mdpi-debug.apk
となります。
画面密度mdpi とABI x86 が有効になったAPKスプリットを含んだ"myApp"のリリースビルドでは、APK のファイル名は myApp-mdpiX86-release.apk
となります。