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

Configura tu compilación

y los empaqueta en APK que puedes probar, implementar, firmar y distribuir.

El sistema de compilación de Android compila recursos y código fuente de la app y los empaqueta en APK que puedes probar, implementar, firmar y distribuir. Android Studio usa Gradle, un paquete de herramientas de compilación avanzadas, para automatizar y administrar el proceso de compilación, y al mismo tiempo definir configuraciones de compilación personalizadas y flexibles. Cada configuración de compilación puede definir su propio conjunto de código y recursos, y reutilizar las partes comunes a todas las versiones de tu app. El complemento de Android para Gradle funciona con el paquete de herramientas de compilación a fin de proporcionar procesos y ajustes configurables específicos para la compilación y prueba de aplicaciones para Android.

Gradle y el complemento de Android se ejecutan independientemente de Android Studio. Por lo tanto, puedes compilar tus apps para Android desde Android Studio, la línea de comandos en tu máquina o en máquinas en las que no esté instalado Android Studio (como servidores de integración continua). Si no usas Android Studio, puedes aprender a compilar y ejecutar tu app desde la línea de comandos. El resultado de la compilación es el mismo si compilas un proyecto desde la línea de comandos en una máquina remota o con Android Studio.

Nota: Como Gradle y el complemento de Android se ejecutan independientemente de Android Studio, debes actualizar las herramientas de compilación por separado. Lee las notas de la versión para obtener información sobre cómo actualizar Gradle y el complemento de Android.

La flexibilidad del sistema de compilación de Android te permite realizar configuraciones de compilación personalizadas sin modificar los archivos de fuente principales de tu app. Esta sección te ayuda a comprender la manera en que funciona el sistema de compilación de Android y cómo puede ayudarte a personalizar y automatizar varias configuraciones de compilación. Si solo quieres obtener más información sobre cómo implementar tu app, consulta la sección sobre compilación y ejecución desde Android Studio. Para comenzar a crear configuraciones de compilación personalizadas de inmediato con Android Studio, consulta Cómo configurar variantes de compilación.

Proceso de compilación

En el proceso de compilación, se incluyen muchas herramientas y procesos que convierten tu proyecto en un paquete de aplicaciones para Android (APK). El proceso de compilación es muy flexible, por lo que resulta útil comprender algo de lo que ocurre en niveles más profundos.

Figura 1: Proceso de compilación típico de un módulo de app para Android

El proceso de compilación para un módulo de app para Android, como se muestra en la figura 1, sigue estos pasos generales:

  1. Los compiladores convierten tu código fuente en archivos DEX (ejecutable de Dalvik), que incluyen el código de bytes que se ejecuta en dispositivos Android, y todo lo demás en recursos compilados.
  2. El empaquetador de APK combina los archivos DEX y los recursos compilados en un solo APK. No obstante, antes de que tu app pueda instalarse y también implementarse en un dispositivo Android, se debe firmar el APK.
  3. El empaquetador de APK firma tu APK usando el almacén de claves de depuración o lanzamiento:
    1. Si compilas una versión de depuración de tu app (es decir, una app que solo desees usar para pruebas y generación de perfiles), el empaquetador firmará tu app con el almacén de claves de depuración. Android Studio configura automáticamente nuevos proyectos con un almacén de claves de depuración.
    2. Si compilas una versión de lanzamiento de tu app que quieres lanzar de manera externa, el empaquetador firmará tu app con el almacén de claves de lanzamiento. Para crear un almacén de claves de lanzamiento, lee la sección sobre cómo firmar apps en Android Studio.
  4. Antes de generar tu APK final, el empaquetador usa la herramienta zipalign para optimizar tu app de modo que use menos memoria cuando se ejecute en un dispositivo.

Al final del proceso de compilación, tendrás un APK de depuración o un APK de lanzamiento de tu app que podrás usar a fin de implementar, probar o lanzar tu app para usuarios externos.

Configuraciones de compilación personalizadas

Gradle y el complemento de Android te ayudan a configurar los siguientes aspectos de tu compilación:

Tipos de compilación
Los tipos de compilación definen determinadas propiedades que Gradle usa al compilar y empaquetar tu app, y generalmente están configurados para diferentes etapas de tu ciclo de vida de desarrollo. Por ejemplo, el tipo de compilación de depuración habilita opciones de depuración y firma el APK con la clave de depuración, mientras que el tipo de compilación de lanzamiento puede reducir, ocultar y firmar tu APK con una clave de lanzamiento para la distribución. Debes definir al menos un tipo de compilación para poder compilar tu app; Android Studio crea los tipos de compilación de depuración y lanzamiento de forma predeterminada. A fin de comenzar a personalizar configuraciones de empaquetado para tu app, obtén información sobre cómo configurar tipos de compilaciones.
Tipos de productos
Los tipos de productos representan diferentes versiones de tu app que puedes lanzar para los usuarios, como las versiones gratuita y paga. Puedes personalizar tipos de productos para usar código y recursos diferentes, y al mismo tiempo compartir y reutilizar las partes comunes a todas las versiones de tu app. Los tipos de productos son opcionales y debes crearlos manualmente. Para comenzar a crear diferentes versiones de tu app, obtén información sobre cómo configurar tipos de productos.
Variantes de compilación
Una variante de compilación es un producto cruzado de un tipo de compilación y un tipo de producto, y es la configuración que Gradle usa para compilar tu app. Usando variantes de compilación, puedes compilar la versión de depuración de tus tipos de productos durante el desarrollo o versiones de lanzamiento firmadas de tus tipos de productos para distribución. Aunque no configuras variantes de compilación directamente, sí configuras los tipos de compilación y los tipos de productos que las forman. La creación de tipos de compilación o tipos de productos adicionales también crea variantes de compilación adicionales. Lee la descripción general Cómo configurar variantes de compilación para obtener información sobre cómo crearlas y administrarlas.
Entradas del manifiesto
Puedes especificar valores para algunas propiedades del archivo de manifiesto en la configuración de la variante de compilación. Estos valores de compilación anulan los valores existentes en el archivo de manifiesto, lo que resulta útil si deseas generar varios APK para tus módulos y que los archivos de cada APK tengan un nombre de aplicación diferente, una versión de SDK mínima o una versión de SDK de destino. Cuando hay varios manifiestos, Gradle fusiona sus configuraciones.
Dependencias
El sistema de compilación administra dependencias del proyecto desde tu sistema de archivos local y desde repositorios remotos. De esta manera, no tienes que buscar, descargar y copiar manualmente paquetes ejecutables de tus dependencias en el directorio de tu proyecto. Para obtener más información, consulta Cómo agregar dependencias de compilación.
Firma
El sistema de compilación te permite especificar configuraciones de firma en la configuración de la compilación, y puede firmar tus APK automáticamente durante el proceso de compilación. El sistema de compilación firma la versión de depuración con una clave y un certificado predeterminados usando credenciales conocidas para evitar la solicitud de una contraseña durante la compilación. El sistema de compilación no firma la versión de lanzamiento, a menos que definas explícitamente una configuración de firma para esta compilación. Si no tienes una clave de lanzamiento, puedes generar una como se describe en Cómo firmar tu app.
ProGuard
El sistema de compilación te permite especificar un archivo de reglas ProGuard diferente para cada variante de compilación. Además, puede ejecutar ProGuard para reducir y ocultar tus clases durante el proceso de compilación.
Compatibilidad con varios APK
El sistema de compilación te permite compilar automáticamente diferentes APK que contengan solo el código y los recursos necesarios para una densidad de pantalla o una interfaz binaria de aplicación (ABI) específica. Para obtener más información, consulta Cómo crear varios APK.

Archivos de configuración de la compilación

Para crear configuraciones de compilación personalizadas, debes realizar cambios en uno o más archivos de configuración de la compilación o en los archivos build.gradle. Estos archivos de texto sin formato usan lenguaje específico de dominio (DSL) para describir y manipular la lógica de compilación mediante Groovy, un lenguaje dinámico para la máquina virtual Java (JVM). No necesitas saber usar Groovy para comenzar a configurar tu compilación, ya que el complemento de Android para Gradle contiene la mayoría de los elementos DSL que necesitas. Para obtener más información sobre el DSL del complemento de Android, lee la documentación de referencia de DSL.

Al comenzar un nuevo proyecto, Android Studio crea automáticamente algunos de esos archivos, como se muestra en la figura 2, y los completa según valores predeterminados confidenciales.

Figura 2: Estructura de proyecto predeterminada para un módulo de app de Android

Hay algunos archivos de configuración de compilación de Gradle que forman parte de la estructura estándar del proyecto para una app de Android. Para que puedas comenzar a configurar tu compilación, es importante que comprendas el alcance y el objetivo de cada uno de esos archivos, y los elementos de DSL básicos que deben definir.

Archivo de configuración de Gradle

El archivo settings.gradle, ubicado en el directorio raíz del proyecto, indica a Gradle los módulos que debe incluir al compilar tu app. Para la mayoría de los proyectos, el archivo es sencillo y solo incluye lo siguiente:

    include ‘:app’
    

No obstante, los proyectos con varios módulos deben especificar cada módulo que formará parte de la compilación final.

Archivo de compilación de nivel superior

El archivo build.gradle de nivel superior, ubicado en el directorio raíz del proyecto, define configuraciones de compilación que se aplican a todos los módulos de tu proyecto. De forma predeterminada, el archivo de nivel superior usa el bloque buildscript para definir los repositorios y las dependencias de Gradle comunes a todos los módulos del proyecto. En el siguiente código de ejemplo, se describen las configuraciones predeterminadas y los elementos de DSL que puedes encontrar en el archivo build.gradle de nivel superior después de crear un proyecto nuevo.

    /**
     * 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()
       }
    }
    

Cómo configurar propiedades de todo un proyecto

Para los proyectos que incluyen varios módulos, puede ser útil definir propiedades en el nivel del proyecto y compartirlas en todos los módulos. Para ello, agrega propiedades adicionales al bloque ext en el archivo build.gradle de nivel superior.

    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"
        ...
    }
    ...
    

Para acceder a estas propiedades desde un módulo del mismo proyecto, usa la siguiente sintaxis en el archivo build.gradle del módulo (obtén más información sobre este archivo en la sección que aparece más abajo).

    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}"
        ...
    }
    

Nota: Aunque Gradle te permite definir las propiedades de todo el proyecto a nivel de módulo, debes evitar hacerlo porque esto provoca que se combinen los módulos que comparten esas propiedades. La combinación del módulo dificulta la exportación posterior como un proyecto autónomo y evita que Gradle utilice la ejecución de un proyecto paralelo para agilizar la compilación de varios módulos.

Archivo de compilación de nivel de módulo

El archivo build.gradle de nivel de módulo, ubicado en cada directorio de project/module/, te permite configurar ajustes de compilación para el módulo específico en el que se encuentra. La configuración de esos ajustes de compilación te permite proporcionar opciones de empaquetado personalizadas, como tipos de compilación y tipos de productos adicionales, y anular las configuraciones en el manifiesto main/ de la app o en el archivo build.gradle de nivel superior.

En este ejemplo de archivo build.gradle del módulo de app para Android, se indican algunos de los elementos y ajustes de DSL básicos que debes conocer.

    /**
     * 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'])
    }
    

Archivos de propiedades de Gradle

Gradle también incluye dos archivos de propiedades, ubicados en el directorio raíz de tu proyecto, que puedes usar para especificar ajustes en el paquete de herramientas de compilación de Gradle:

gradle.properties
Aquí puedes configurar ajustes Gradle para todo el proyecto, como el tamaño máximo del montón de daemon de Gradle. Para obtener más información, consulta Entorno de compilación.
local.properties
Configura propiedades del entorno local para el sistema de compilación, como la ruta de acceso de instalación del SDK. Como Android Studio genera automáticamente el contenido de este archivo y es específico para el entorno del desarrollador local, no debes modificar este archivo de forma manual ni incluirlo en tu sistema de control de versión.

Sincronización del proyecto con archivos de Gradle

Cuando realizas cambios en los archivos de configuración de la compilación de tu proyecto, Android Studio exige que sincronices los archivos de tu proyecto para poder importar tus cambios a la configuración de la compilación y ejecutar algunas comprobaciones a fin de controlar que tu configuración no genere errores de compilación.

Para sincronizar los archivos de tu proyecto, haz clic en Sincronizar ahora en la barra de notificaciones que aparece cuando realizas un cambio, como se muestra en la figura 3, o haz clic en Sincronizar proyecto en la barra de menú. Si Android Studio detecta errores en tu configuración (por ejemplo, tu código fuente usa funciones de API que solo están disponibles en un nivel de API superior al de tu compileSdkVersion), aparece la ventana Mensajes con la descripción del problema.

Figura 3: Sincronización del proyecto con archivos de configuración de compilación en Android Studio

Conjuntos de fuentes

Android Studio agrupa de forma lógica código fuente y recursos para cada módulo en conjuntos de fuentes. El conjunto de fuentes main/ del módulo incluye el código y los recursos empleados por todas sus variantes de compilación. Los directorios adicionales del conjunto de fuentes son opcionales, y Android Studio no los crea automáticamente cuando configuras nuevas variantes de compilación. No obstante, crear conjuntos de fuentes (caso similar al de main/) te ayuda a organizar archivos y recursos que Gradle solo debe usar al compilar ciertas versiones de tu app:

src/main/
Este conjunto de fuentes incluye el código y los recursos comunes a todas las variantes de compilación.
src/buildType/
Crea este conjunto de fuentes a fin de incluir código y recursos solo para un tipo de compilación específico.
src/productFlavor/
Crea este conjunto de fuentes a fin de incluir código y recursos solo para un tipo de producto específico.

Nota: Si configuras tu compilación para que combine varios tipos de productos, puedes crear directorios para conjuntos de fuentes de cada combinación de tipos de producto entre las siguientes dimensiones: src/productFlavor1ProductFlavor2/

src/productFlavorBuildType/
Crea este conjunto de fuentes a fin de incluir código y recursos solo para una variante de compilación específica.

Por ejemplo, para generar la versión "fullDebug" de tu app, el sistema de compilación fusiona código, configuraciones y recursos de los siguientes conjuntos de fuentes:

  • src/fullDebug/ (conjunto de fuentes de la variante de compilación)
  • src/debug/ (conjunto de fuentes del tipo de compilación)
  • src/full/ (conjunto de fuentes del tipo de producto)
  • src/main/ (conjunto de fuentes principal)

Nota: Cuando creas un archivo o directorio nuevo en Android Studio mediante las opciones del menú Archivo > Nuevo, puedes crearlo para un conjunto de fuentes específico. Los conjuntos de fuentes entre los que puedes elegir se basan en tus configuraciones de compilación, y Android Studio crea automáticamente los directorios necesarios, en caso de que no existan.

Si diferentes conjuntos de fuentes contienen distintas versiones del mismo archivo, Gradle usa el siguiente orden de prioridad para determinar el archivo que se usará (los conjuntos de fuentes de la izquierda anulan los archivos y las configuraciones de los conjuntos de fuentes de la derecha):

variante de compilación > tipo de compilación > tipo de producto > conjunto de fuentes principal > dependencias de biblioteca

De esta manera, Gradle puede usar archivos específicos para la variante de compilación que intentas compilar y, al mismo tiempo, reutilizar las actividades, la lógica de aplicación y los recursos comunes a otras versiones de tu app. Cuando se fusionan varios manifiestos, Gradle usa el mismo orden de prioridad, de modo que cada variante de compilación pueda definir diferentes componentes o permisos en el manifiesto final. Para obtener más información sobre cómo crear conjuntos de fuentes personalizados, dirígete a Cómo crear conjuntos de fuentes para variantes de compilación.