Android Dev Summit, October 23-24: two days of technical content, directly from the Android team. Sign-up for livestream updates.

ビルドを設定する

Android ビルドシステムは、アプリリソースとソースコードをコンパイルして、テスト、デプロイ、署名、配布が可能な APK にパッケージ化します。

Android ビルドシステムは、アプリリソースとソースコードをコンパイルして、テスト、デプロイ、署名、配布が可能な APK にパッケージ化します。Android Studio は、高度なビルド ツールキットである Gradle を使用することで、ビルドプロセスを自動化して管理しつつ、柔軟なカスタムビルド設定を定義することができます。各ビルド設定でそれぞれ独自のコードとリソースのセットを定義しつつ、すべてのアプリ バージョンに共通する部分を再利用することが可能です。Android Plugin for Gradle はビルド ツールキットと連携して、Android アプリのビルドとテストに固有のプロセスや構成可能な設定を提供します。

Gradle と Android プラグインは Android Studio から独立して実行されます。つまり、Android Studio からでも、使用しているマシンのコマンドラインからでも、Android Studio がインストールされていないマシン(継続的インテグレーション サーバーなど)のコマンドラインからでも、Android アプリをビルドすることができます。Android Studio を使用していない場合は、コマンドラインからアプリをビルドして実行する方法についてご確認ください。コマンドライン、リモートマシン、Android Studio のいずれからプロジェクトをビルドした場合でも、ビルドの出力は同じになります。

注: Gradle と Android プラグインは Android Studio から独立して実行されるため、各ビルドツールはそれぞれ個別にアップデートする必要があります。Gradle と Android プラグインをアップデートする方法については、リリースノートをご覧ください。

Android ビルドシステムは柔軟であり、アプリの主要ソースファイルを変更せずに、カスタムビルド設定を行うことができます。このセクションでは、Android ビルドシステムの仕組みと、Android ビルドシステムを通じて複数のビルド設定をカスタマイズ、自動化する方法について説明します。アプリをデプロイする方法については、Android Studio からビルドして実行するをご覧ください。Android Studio を使用してカスタムビルド設定の作成をすぐに開始する場合は、ビルド バリアントを設定するをご覧ください。

ビルドプロセス

ビルドプロセスには、プロジェクトを Android アプリ パッケージ(APK)に変換するさまざまなツールやプロセスが含まれます。ビルドプロセスは非常に柔軟であるため、内部でどのような処理が実行されているのかを理解しておくと役に立ちます。

図 1: 一般的な Android アプリ モジュールのビルドプロセス。

図 1 に示した一般的な Android アプリ モジュールのビルドプロセスの場合、通常は次のようなステップで構成されます。

  1. コンパイラが、ソースコードを DEX(Dalvik Executable)ファイルに変換します。このファイルには、Android デバイス上で稼働するバイトコードが格納されます。ソースコード以外の要素はすべて、コンパイル済みリソースに変換されます。
  2. APK Packager が、DEX ファイルとコンパイル済みリソースを単一の APK に結合します。ただし、アプリを Android デバイスにインストール、デプロイする前に、APK に署名する必要があります。
  3. APK Packager が、デバッグ キーストアまたはリリース キーストアを使用して、APK に署名します。
    1. アプリのデバッグ バージョン(テストやプロファイリング専用のアプリ)をビルドする場合、Packager はデバッグ キーストアを使用してアプリに署名します。Android Studio は、デバッグ キーストアを使用して新しいプロジェクトを自動的に設定します。
    2. アプリのリリース バージョン(一般公開用)をビルドする場合、Packager はリリース キーストアを使用してアプリに署名します。リリース キーストアを作成する方法については、Android Studio 内でアプリに署名するをご覧ください。
  4. 最終 APK を生成する前に、Packager は、zipalign ツールを使用してアプリを最適化し、アプリがデバイス上で稼働するときのメモリ使用量を削減します。

ビルドプロセスの最後に生成されるアプリのデバッグ APK またはリリース APK を使用して、デプロイ、テスト、外部ユーザーへのリリースを行うことができます。

カスタムビルド設定

Gradle と Android プラグインを使用すると、以下のビルド要素を設定できます。

ビルドタイプ
ビルドタイプは、アプリをビルドしてパッケージ化する際に Gradle が使用するプロパティを定義します。通常、ビルドタイプは、開発ライフサイクル内の各段階に応じて設定されます。たとえば、デバッグ ビルドタイプの場合、デバッグ オプションが有効化され、デバッグキーを使用して APK に署名します。リリース ビルドタイプの場合、圧縮や難読化が実行され、リリースキーを使用して APK に署名し、配布が行われます。アプリをビルドするには、少なくとも 1 つのビルドタイプを定義する必要があります。Android Studio は、デフォルトでデバッグ ビルドタイプとリリース ビルドタイプを作成します。アプリのパッケージ設定のカスタマイズを開始する場合は、ビルドタイプを設定するをご覧ください。
プロダクト フレーバー
プロダクト フレーバーは、アプリの無料版や有料版など、ユーザーにリリースする各アプリ バージョンを示します。プロダクト フレーバーをカスタマイズすることで、異なるコードやリソースを使用しつつ、すべてのアプリ バージョンに共通する部分を共有し再利用することができます。プロダクト フレーバーはオプションであり、手動で作成する必要があります。さまざまなアプリ バージョンの作成を開始する場合は、プロダクト フレーバーを設定するをご覧ください。
ビルド バリアント
ビルド バリアントは、ビルドタイプとプロダクト フレーバーを組み合わせたものです。Gradle はこの設定を使用してアプリをビルドします。ビルド バリアントを利用することで、開発時にはプロダクト フレーバーのデバッグ バージョンをビルドし、配布時にはプロダクト フレーバーの署名付きリリース バージョンをビルドすることができます。ビルド バリアントは直接設定するものではなく、ビルド バリアントを構成するビルドタイプとプロダクト フレーバーを設定します。追加のビルドタイプやプロダクト フレーバーを作成すると、それに応じてビルド バリアントも追加作成されます。ビルド バリアントを作成、管理する方法については、ビルド バリアントを設定するをご覧ください。
マニフェスト エントリ
ビルド バリアントの設定で、マニフェスト ファイルの一部のプロパティの値を指定することができます。このビルド値は、マニフェスト ファイル内の既存の値をオーバーライドします。このオーバーライドは、モジュールに対して複数の APK を生成し、各 APK ファイルにそれぞれ異なるアプリ名、最小 SDK バージョン、ターゲット SDK バージョンを指定する場合に便利です。マニフェストが複数存在する場合、Gradle はマニフェスト設定をマージします。
依存関係
ビルドシステムは、ローカル ファイル システムやリモート リポジトリのプロジェクト依存関係を管理します。これにより、依存関係のバイナリ パッケージを手動で検索してダウンロードしたり、プロジェクト ディレクトリにコピーしたりする必要がなくなります。詳細については、ビルドの依存関係を追加するをご覧ください。
署名
ビルドシステムを使用すると、ビルド設定内で署名設定を指定し、ビルドプロセス中に APK に自動的に署名することができます。デバッグ バージョンの場合、ビルドシステムは、既知の認証情報を使用してデフォルトのキーと証明書で署名を行い、ビルド時にパスワード プロンプトが表示されないようにします。リリース バージョンの場合、対象ビルドの署名設定を明示的に定義していない限り、署名は行いません。リリースキーがない場合は、リリースキーを生成することができます。生成方法については、アプリに署名するをご覧ください。
ProGuard
ビルドシステムを使用すると、各ビルド バリアントに対してそれぞれ異なる ProGuard ルールファイルを指定することができます。ビルドシステムは、ProGuard を実行することで、ビルドプロセス中にクラスの圧縮や難読化を行うことができます。
複数 APK のサポート
ビルドシステムを使用すると、それぞれ特定の画面密度やアプリケーション バイナリ インターフェース(ABI)に必要なコードとリソースだけを格納した各種 APK を自動的にビルドすることができます。詳細については、複数の APK をビルドするをご覧ください。

ビルド設定ファイル

カスタムビルド設定を作成するには、1 つまたは複数のビルド設定ファイル(build.gradle ファイル)に変更を加える必要があります。このプレーン テキスト ファイルは、ドメイン固有言語(DSL)を使用しており、Groovy を使用してビルドロジックを記述、処理します。Groovy は Java 仮想マシン(JVM)用の動的言語です。Android Plugin for Gradle には必要な DSL 要素のほとんどが導入されているため、ビルド設定を開始する際、Groovy に関する知識は必要ありません。Android プラグイン DSL の詳細については、DSL リファレンス ドキュメントをご覧ください。

新しいプロジェクトを開始すると、図 2 のように、Android Studio が一部のファイルを自動的に作成し、適切なデフォルト値に基づいて、ファイルを設定します。

図 2: Android アプリ モジュールのデフォルト プロジェクト構造。

Android アプリの標準プロジェクト構造には、数種類の Gradle ビルド設定ファイルが含まれています。ビルドの設定を開始する前に、各ファイルの対象範囲や目的、定義する必要のある基本的 DSL 要素について理解しておくことが重要です。

Gradle 設定ファイル

ルート プロジェクト ディレクトリにある settings.gradle ファイルに基づいて、Gradle は、アプリをビルドする際に含める必要のあるモジュールを識別します。大部分のプロジェクトにおいて、このファイルはシンプルな構成をしており、以下の要素だけを格納しています。

    include ‘:app’
    

ただし、マルチモジュールのプロジェクトの場合、最終ビルドに含める必要のある各モジュールを指定する必要があります。

トップレベル ビルドファイル

ルート プロジェクト ディレクトリにあるトップレベルの build.gradle ファイルは、プロジェクト内のすべてのモジュールに適用されるビルド設定を定義します。デフォルトでは、このトップレベル ビルドファイルは buildscript ブロックを使用して、プロジェクト内のすべてのモジュールに共通する Gradle リポジトリと依存関係を定義します。新しいプロジェクトを作成した後にトップレベルの build.gradle 内で見つけることができるデフォルト設定と DSL 要素について、下記のサンプルコードに示します。

    /**
     * The buildscript block is where you configure the repositories and
     * dependencies for Gradle itself—meaning, you should not include dependencies
     * for your modules here. For example, this block includes the Android plugin for
     * Gradle as a dependency because it provides the additional instructions Gradle
     * needs to build Android app modules.
     */

    buildscript {

        /**
         * The repositories block configures the repositories Gradle uses to
         * search or download the dependencies. Gradle pre-configures support for remote
         * repositories such as JCenter, Maven Central, and Ivy. You can also use local
         * repositories or define your own remote repositories. The code below defines
         * JCenter as the repository Gradle should use to look for its dependencies.
         *
         * New projects created using Android Studio 3.0 and higher also include
         * Google's Maven repository.
         */

        repositories {
            google()
            jcenter()
        }

        /**
         * The dependencies block configures the dependencies Gradle needs to use
         * to build your project. The following line adds Android plugin for Gradle
         * version 3.4.2 as a classpath dependency.
         */

        dependencies {
            classpath 'com.android.tools.build:gradle:3.4.2'
        }
    }

    /**
     * The allprojects block is where you configure the repositories and
     * dependencies used by all modules in your project, such as third-party plugins
     * or libraries. However, you should configure module-specific dependencies in
     * each module-level build.gradle file. For new projects, Android Studio
     * includes JCenter and Google's Maven repository by default, but it does not
     * configure any dependencies (unless you select a template that requires some).
     */

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

プロジェクト レベルのプロパティを設定する

複数のモジュールを含む Android プロジェクトの場合は、プロジェクト レベルで特定のプロパティを定義し、それをすべてのモジュールで共有すると便利です。そのためには、トップレベルの build.gradle ファイル内の ext ブロックで、追加のプロパティを定義します。

    buildscript {...}

    allprojects {...}

    // This block encapsulates custom properties and makes them available to all
    // modules in the project.
    ext {
        // The following are only a few examples of the types of properties you can define.
        compileSdkVersion = 28
        // You can also create properties to specify versions for dependencies.
        // Having consistent versions between modules can avoid conflicts with behavior.
        supportLibVersion = "28.0.0"
        ...
    }
    ...
    

同一プロジェクト内の個々のモジュールからこのプロパティにアクセスするには、モジュールの build.gradle ファイル(このファイルの詳細については下記を参照)内で次の構文を使用します。

    android {
      // Use the following syntax to access properties you defined at the project level:
      // rootProject.ext.property_name
      compileSdkVersion rootProject.ext.compileSdkVersion
      ...
    }
    ...
    dependencies {
        implementation "com.android.support:appcompat-v7:${rootProject.ext.supportLibVersion}"
        ...
    }
    

注: Gradle では、プロジェクト レベルのプロパティをモジュール レベルで定義することもできますが、その場合、プロパティを共有するモジュールが結合されてしまうため、この方法は避けてください。モジュールが結合すると、後でスタンドアロンのプロジェクトとして個々のモジュールをエクスポートするのが困難になります。そのため、Gradle は、並列プロジェクト実行を使用してマルチモジュール ビルドを高速化することが事実上不可能になります。

モジュール レベル ビルドファイル

project/module/ ディレクトリにあるモジュール レベルの build.gradle ファイルを使用すると、そのファイルが属する個々のモジュールのビルド設定を指定することができます。モジュール レベルでビルド設定を指定した場合、追加のビルドタイプやプロダクト フレーバーなど、カスタム パッケージ オプションを設定することで、main/ アプリ マニフェスト内やトップレベルの build.gradle ファイル内の設定をオーバーライドすることができます。

把握しておくべき基本的な DSL 要素と設定の概要について、下記のサンプル Android アプリ モジュールの build.gradle ファイルに示します。

    /**
     * The first line in the build configuration applies the Android plugin for
     * Gradle to this build and makes the android block available to specify
     * Android-specific build options.
     */

    apply plugin: 'com.android.application'

    /**
     * The android block is where you configure all your Android-specific
     * build options.
     */

    android {

      /**
       * compileSdkVersion specifies the Android API level Gradle should use to
       * compile your app. This means your app can use the API features included in
       * this API level and lower.
       */

      compileSdkVersion 28

      /**
       * buildToolsVersion specifies the version of the SDK build tools, command-line
       * utilities, and compiler that Gradle should use to build your app. You need to
       * download the build tools using the SDK Manager.
       *
       * This property is optional because the plugin uses a recommended version of
       * the build tools by default.
       */

      buildToolsVersion "29.0.0"

      /**
       * The defaultConfig block encapsulates default settings and entries for all
       * build variants, and can override some attributes in main/AndroidManifest.xml
       * dynamically from the build system. You can configure product flavors to override
       * these values for different versions of your app.
       */

      defaultConfig {

        /**
         * applicationId uniquely identifies the package for publishing.
         * However, your source code should still reference the package name
         * defined by the package attribute in the main/AndroidManifest.xml file.
         */

        applicationId 'com.example.myapp'

        // Defines the minimum API level required to run the app.
        minSdkVersion 15

        // Specifies the API level used to test the app.
        targetSdkVersion 28

        // Defines the version number of your app.
        versionCode 1

        // Defines a user-friendly version name for your app.
        versionName "1.0"
      }

      /**
       * The buildTypes block is where you can configure multiple build types.
       * By default, the build system defines two build types: debug and release. The
       * debug build type is not explicitly shown in the default build configuration,
       * but it includes debugging tools and is signed with the debug key. The release
       * build type applies Proguard settings and is not signed by default.
       */

      buildTypes {

        /**
         * By default, Android Studio configures the release build type to enable code
         * shrinking, using minifyEnabled, and specifies the Proguard settings file.
         */

        release {
            minifyEnabled true // Enables code shrinking for the release build type.
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
      }

      /**
       * The productFlavors block is where you can configure multiple product flavors.
       * This allows you to create different versions of your app that can
       * override the defaultConfig block with their own settings. Product flavors
       * are optional, and the build system does not create them by default.
       *
       * This example creates a free and paid product flavor. Each product flavor
       * then specifies its own application ID, so that they can exist on the Google
       * Play Store, or an Android device, simultaneously.
       *
       * If you declare product flavors, you must also declare flavor dimensions
       * and assign each flavor to a flavor dimension.
       */

      flavorDimensions "tier"
      productFlavors {
        free {
          dimension "tier"
          applicationId 'com.example.myapp.free'
        }

        paid {
          dimension "tier"
          applicationId 'com.example.myapp.paid'
        }
      }

      /**
       * The splits block is where you can configure different APK builds that
       * each contain only code and resources for a supported screen density or
       * ABI. You'll also need to configure your build so that each APK has a
       * different versionCode.
       */

      splits {
        // Settings to build multiple APKs based on screen density.
        density {

          // Enable or disable building multiple APKs.
          enable false

          // Exclude these densities when building multiple APKs.
          exclude "ldpi", "tvdpi", "xxxhdpi", "400dpi", "560dpi"
        }
      }
    }

    /**
     * The dependencies block in the module-level build configuration file
     * specifies dependencies required to build only the module itself.
     * To learn more, go to Add build dependencies.
     */

    dependencies {
        implementation project(":lib")
        implementation 'com.android.support:appcompat-v7:28.0.0'
        implementation fileTree(dir: 'libs', include: ['*.jar'])
    }
    

Gradle プロパティ ファイル

また、ルート プロジェクト ディレクトリには、2 つの Gradle プロパティ ファイルがあります。このファイルを使用することで、Gradle ビルド ツールキット自体の設定を指定することができます。

gradle.properties
Gradle デーモンの最大ヒープサイズなど、プロジェクト レベルの Gradle 設定を指定できます。詳細については、ビルド環境をご覧ください。
local.properties
SDK インストールのパスなど、ビルドシステムのローカル環境プロパティを設定します。このファイルのコンテンツは、Android Studio によって自動的に生成され、ローカル デベロッパー環境に固有のものであるため、このファイルを手動で変更したり、バージョン管理システムにチェックインしたりしないでください。

プロジェクトと Gradle ファイルを同期する

プロジェクト内のビルド設定ファイルに変更を加えた場合、プロジェクト ファイルを同期するよう Android Studio から求められます。同期すると、ビルド設定の変更をインポートして、設定がビルドエラーを引き起こさないか確認するチェックを実行できるようになります。

プロジェクト ファイルを同期するには、変更を加えたときに表示される通知バーで [Sync Now] をクリックするか(図 3 を参照)、メニューバーから [Sync Project]()をクリックします。Android Studio が設定に関するエラー(たとえば、指定されている compileSdkVersion よりも上位の API レベルでなければ利用できない API 機能をソースコードが使用しているケース)を認識した場合、問題の説明を記載した [Messages] ウィンドウが表示されます。

図 3: Android Studio 内で行うプロジェクトとビルド設定ファイルの同期。

ソースセット

Android Studio は、各モジュールのソースコードとリソースを「ソースセット」として論理的にグループ化します。モジュールの main/ ソースセットには、すべてのビルド バリアントが使用するコードとリソースが含まれます。追加のソースセット ディレクトリはオプションであり、新しいビルド バリアントを設定しても、そのソースセット ディレクトリを Android Studio が自動的に作成することはありません。main/ と同様のソースセットを作成しておくと、アプリの特定バージョンをビルドするときにのみ Gradle が使用するファイルとリソースを整理することができます。

src/main/
このソースセットには、すべてのビルド バリアントに共通するコードとリソースが含まれています。
src/buildType/
特定のビルドタイプ用のコードとリソースだけを含めるには、このソースセットを作成します。
src/productFlavor/
特定のプロダクト フレーバー用のコードとリソースだけを含めるには、このソースセットを作成します。

注: 複数のプロダクト フレーバーを組み合わせるようにビルドを設定した場合、フレーバー ディメンション間のプロダクト フレーバーの各組み合わせを対象とするソースセット ディレクトリを作成することができます(src/productFlavor1ProductFlavor2/)。

src/productFlavorBuildType/
特定のビルド バリアント用のコードとリソースだけを含めるには、このソースセットを作成します。

たとえば、アプリの「fullDebug」バージョンを生成する場合、ビルドシステムは以下のソースセットのコード、設定、リソースをマージします。

  • src/fullDebug/(ビルド バリアントのソースセット)
  • src/debug/(ビルドタイプのソースセット)
  • src/full/(プロダクト フレーバーのソースセット)
  • src/main/(メインのソースセット)

注: Android Studio 内で新しいファイルやディレクトリを作成する際、[File] > [New] メニュー オプションを使用すると、特定のソースセット用のファイルやディレクトリを作成できます。ビルド設定に応じてソースセットを選択することができ、必要なディレクトリが存在しない場合は、Android Studio が自動的に作成します。

異なるソースセット内に、同一ファイルの別バージョンが含まれている場合、Gradle は、次の優先順位に基づいて、使用するファイルを決定します(左側のソースセットが右側のソースセットのファイルや設定をオーバーライドします)。

ビルド バリアント > ビルドタイプ > プロダクト フレーバー > メイン ソースセット > ライブラリ依存関係

これにより、Gradle は、ビルドしようとしているビルド バリアントに固有のファイルを使用しつつ、他のアプリ バージョンと共通するアクティビティ、アプリロジック、リソースを再利用できるようになります。Gradle が複数のマニフェストをマージする際も、同じ優先順位が使用されるため、ビルド バリアントごとに最終マニフェスト内でさまざまなコンポーネントやパーミッションを定義できます。カスタム ソースセットの作成方法については、ビルド バリアントのソースセットを作成するをご覧ください。