Cómo crear una biblioteca de Android

Una biblioteca de Android tiene la misma estructura que un módulo de app de Android. Incluye todo lo que se necesita para compilar una app, como el código fuente, archivos de recursos y un manifiesto de Android.

Sin embargo, en lugar de compilarse en un APK que se ejecute en un dispositivo, una biblioteca de Android se compila en un archivo Android ARchive (AAR) que puedes usar como dependencia para un módulo de app para Android. A diferencia de los archivos JAR, los archivos AAR ofrecen las siguientes funciones para las apps para Android:

  • Los archivos AAR pueden contener recursos de Android y un archivo de manifiesto, que te permite incluir recursos compartidos, como diseños y elementos de diseño, además de clases y métodos de Kotlin o Java.
  • Los archivos AAR pueden contener bibliotecas C o C++ para que los use el código C o C++ del módulo de la app.

Un módulo de biblioteca es útil en las siguientes situaciones:

  • Cuando compilas varias apps que comparten algunos componentes, como actividades, servicios o diseños de la IU
  • Cuando compilas una app que existe en diferentes variantes del APK, como una versión gratuita y una versión pagada, que comparten componentes principales

En cualquier caso, mueve los archivos que desees volver a usar a un módulo de biblioteca y, luego, agrega la biblioteca como una dependencia para cada módulo de app.

En esta página, se explica cómo crear y usar un módulo de biblioteca de Android. Si deseas obtener instrucciones para publicar una biblioteca, consulta Cómo publicar tu biblioteca

Cómo crear un módulo de biblioteca

Para crear un módulo de biblioteca en tu proyecto, haz lo siguiente:

  1. Haz clic en File > New > New Module.
  2. En el diálogo Create New Module que aparece, haz clic en Android Library y, luego, en Next.

    También se puede crear una biblioteca de Kotlin o Java, que compila un archivo JAR tradicional. Si bien un archivo JAR es útil para muchos proyectos, en especial cuando deseas compartir el código con otras plataformas, no te permite incluir archivos de manifiesto ni recursos de Android, y esto es muy útil para reutilizar el código en proyectos de Android. Esta guía se enfoca en la creación de bibliotecas de Android.

  3. Otorga un nombre a la biblioteca y selecciona una versión mínima del SDK para el código de la biblioteca. Luego, haz clic en Finish.

Una vez que se haya completado la sincronización del proyecto de Gradle, se mostrará el módulo de la biblioteca en el panel Project. Si no ves la nueva carpeta del módulo, asegúrate de que el panel muestre la vista de Android.

Cómo convertir un módulo de app en un módulo de biblioteca

Si tienes un módulo de app existente con el código que deseas reutilizar, puedes convertirlo en un módulo de biblioteca de la siguiente manera:

  1. Abre el archivo build.gradle a nivel del módulo, si usas Groovy, o el archivo build.gradle.kts, si usas la secuencia de comandos de Kotlin.
  2. Borra la línea para applicationId. Solo un módulo de la app para Android puede definir esto.
  3. Busca el bloque "plugins" en la parte superior del archivo que se ve de la siguiente manera:

    Groovy

      plugins {
          id 'com.android.application'
      }
      

    Kotlin

      plugins {
          id("com.android.application")
      }
      

    Cámbialo por lo siguiente:

    Groovy

      plugins {
          id 'com.android.library'
      }
      

    Kotlin

      plugins {
          id("com.android.library")
      }
      
  4. Guarda el archivo y haz clic en File > Sync Project with Gradle Files.

La estructura del módulo sigue siendo la misma, pero ahora funciona como una biblioteca de Android. La compilación crea un archivo AAR en lugar de un APK.

Cuando desees compilar el archivo AAR, selecciona el módulo de biblioteca en la ventana Project y haz clic en Build > Build APK.

Cómo agregar dependencias con el diálogo Project Structure

Puedes usar el diálogo Project Structure para agregar dependencias a tu proyecto. En las siguientes secciones, se describe cómo usar el diálogo para agregar dependencias.

Cómo usar tu biblioteca desde el mismo proyecto

Para usar código de tu nueva biblioteca de Android en otra app u otro módulo de biblioteca dentro del mismo proyecto, agrega una dependencia a nivel de proyecto:

  1. Ve a File > Project Structure > Dependencies.
  2. Selecciona el módulo que quieres agregar a la biblioteca.
  3. En la pestaña Declared Dependencies, haz clic en y selecciona Module Dependency en el menú.

  4. En el diálogo Add Module Dependency, selecciona tu módulo de biblioteca.

    Cómo agregar una dependencia de módulo en el diálogo Project Structure

  5. Selecciona la configuración que requiere esta dependencia o elige implementation, si se aplica a todas las configuraciones, y haz clic en OK.

Android Studio edita el archivo build.gradle o build.gradle.kts de tu módulo para agregar la dependencia de la siguiente manera:

Groovy

  implementation project(path: ":example-library")

Kotlin

  implementation(project(":example-library"))

Cómo usar tu biblioteca en otros proyectos

La forma recomendada de compartir dependencias (JARs y AARs) es con un repositorio de Maven, alojado en un servicio como Maven Central o con una estructura de directorio en tu disco local. Para obtener más información sobre el uso de repositorios de Maven, consulta Repositorios remotos.

Cuando se publica una biblioteca de Android en un repositorio de Maven, se incluyen los metadatos para que las dependencias de la biblioteca se incluyan en la compilación que las usa. Esto permite que se anule automáticamente el duplicado de la biblioteca si se usa en varios lugares.

Para usar el código de la biblioteca de Android en otro módulo de app de un proyecto diferente, haz lo siguiente:

  1. Ve a File > Project Structure > Dependencies.
  2. En la pestaña Declared Dependencies, haz clic en y selecciona Library Dependency en el menú.

  3. En el diálogo Add Library Dependency, usa el cuadro de búsqueda para buscar la biblioteca que quieres agregar. Mediante este formulario, se buscan los repositorios especificados en el bloque dependencyResolutionManagement { repositories {...}} del archivo settings.gradle o settings.gradle.kts.

    Cómo agregar la dependencia de la biblioteca en el diálogo Project Structure

  4. Selecciona la configuración que requiere esta dependencia o elige implementation, si se aplica a todas las configuraciones, y haz clic en OK.

Revisa el archivo build.gradle o build.gradle.kts de tu app para confirmar que aparezca una declaración similar a la siguiente (según la configuración de compilación que hayas seleccionado):

Groovy

  implementation 'com.example:examplelibrary:1.0.0'

Kotlin

  implementation("com.example:examplelibrary:1.0.0")

Cómo agregar tu AAR o JAR como una dependencia

Para usar el código de la biblioteca de Android en otro módulo de app, haz lo siguiente:

  1. Ve a File > Project Structure > Dependencies.
  2. En la pestaña Declared Dependencies, haz clic en y selecciona Jar Dependency en el menú.

  3. En el diálogo Add Jar/Aar Dependency, ingresa la ruta de acceso a tu archivo AAR o JAR, y luego selecciona la configuración a la que se aplica la dependencia. Si la biblioteca debería estar disponible para todas las configuraciones, selecciona la configuración de implementation.

    Cómo agregar la dependencia AAR en el diálogo Project Structure

    Revisa el archivo build.gradle o build.gradle.kts de tu app para confirmar que aparezca una declaración similar a la siguiente (según la configuración de compilación que hayas seleccionado):

    Groovy

      implementation files('my_path/my_lib.aar')
    

    Kotlin

      implementation(files("my_path/my_lib.aar"))
    

Para importar una dependencia en la compilación de Gradle que se ejecuta fuera de Android Studio, agrega una ruta de acceso a la dependencia en el archivo build.gradle o build.gradle.kts de tu app. Por ejemplo:

Groovy

dependencies {
    implementation fileTree(dir: "libs", include: ["*.jar", "*.aar"])
}

Kotlin

dependencies {
    implementation(fileTree(mapOf("dir" to "libs", "include" to listOf("*.jar", "*.aar"))))
}

Para obtener más información sobre cómo agregar dependencias de Gradle, consulta Cómo agregar dependencias de compilación.

Cómo declarar un recurso público

Los recursos incluyen todos los archivos en el directorio res/ de tu proyecto, como imágenes. El valor predeterminado de todos los recursos de una biblioteca es "public". Para hacer que todos los recursos sean privados de forma implícita, debes definir al menos un atributo específico como "public".

Para declarar un recurso público, agrega una declaración <public> al archivo public.xml de la biblioteca. Si no agregaste recursos públicos antes, debes crear el archivo public.xml en el directorio res/values/ de la biblioteca.

En el siguiente código de ejemplo, se crean dos recursos de cadenas públicos con los nombres mylib_app_name y mylib_public_string:

<resources>
    <public name="mylib_app_name" type="string"/>
    <public name="mylib_public_string" type="string"/>
</resources>

Para evitar que los usuarios de la biblioteca accedan a recursos previstos únicamente para uso interno, debes utilizar este mecanismo de designación privado automático mediante la declaración de uno o más recursos públicos. De forma alternativa, puedes convertir todos los recursos en privados si agregas una etiqueta <public /> vacía. Esta etiqueta no marca nada como público, sino todo como privado (todos los recursos).

Los recursos que desees mantener visibles para los desarrolladores que usan tu biblioteca deben ser públicos.

Hacer los atributos privados de forma implícita evita que los usuarios de tu biblioteca reciban sugerencias de finalización de código desde recursos internos de la biblioteca y permite a los usuarios cambiar los nombres de los recursos privados o quitarlos sin afectar a los clientes de la biblioteca. Los recursos privados se filtran al finalizar el código, y la herramienta lint muestra una advertencia cuando intentas hacer referencia a un recurso privado.

Cuando compilas una biblioteca, el complemento de Android para Gradle obtiene las definiciones de recursos públicos y las extrae en el archivo public.txt, que luego se empaqueta dentro del archivo AAR.

Consideraciones de desarrollo para módulos de biblioteca

Cuando desarrolles los módulos de biblioteca y las apps dependientes, ten en cuenta los comportamientos y las limitaciones que se indican a continuación.

  • Las bibliotecas se combinan en orden de prioridad.

    Una vez que hayas agregado referencias a módulos de biblioteca en el módulo de app para Android, podrás establecer su prioridad relativa. Durante el tiempo de compilación, se combinarán las bibliotecas con la app de a una, de menor a mayor prioridad.

  • Evita los conflictos de combinación de recursos.

    Las herramientas de compilación combinan los recursos de un módulo de biblioteca con los de un módulo de app dependiente. Si se define un ID de recurso específico en ambos módulos, se usará el recurso de la app.

    Si ocurren conflictos entre varias bibliotecas AAR, se usa el recurso de la biblioteca que se ubica primero en la lista de dependencias (cerca de la parte superior del bloque de dependencies).

    Para evitar conflictos de recursos, usa clases R no transitivas. Si no es posible, considera usar un prefijo o cualquier otro esquema de nombramiento coherente que sea exclusivo del módulo (o de todos los módulos del proyecto).

  • En las compilaciones de varios módulos, las dependencias JAR se tratan como dependencias transitivas.

    Cuando se agrega una dependencia JAR a un proyecto de biblioteca que genera un AAR, el módulo de biblioteca procesa el JAR y lo empaqueta con su AAR.

    Sin embargo, si el proyecto incluye un módulo de biblioteca que un módulo de app consume, el módulo de app trata la dependencia JAR local de la biblioteca como una dependencia transitiva. En este caso, el JAR local es procesado por el módulo de la app que lo consume, y no por el módulo de la biblioteca. Esto tiene como objetivo acelerar las compilaciones incrementales producidas por cambios en el código de la biblioteca.

    Cualquier conflicto de recursos Java causado por dependencias JAR locales debe resolverse en el módulo de la app que consume la biblioteca.

  • Un módulo de biblioteca puede depender de una biblioteca JAR externa.

    Puedes desarrollar un módulo de biblioteca que dependa de una biblioteca externa. En este caso, el módulo dependiente debe realizar compilaciones en un objetivo que incluya la biblioteca externa.

    Ten en cuenta que el módulo de biblioteca y la app dependiente deben declarar la biblioteca externa en sus archivos de manifiesto, en un elemento <uses-library>.

  • El valor de minSdkVersion del módulo de app debe ser igual o mayor que la versión definida por la biblioteca.

    Una biblioteca se compila como parte del módulo de app dependiente; por ello, las APIs que se usan en el módulo de biblioteca deben ser compatibles con la versión de plataforma que admite el módulo de la app.

  • Cada módulo de biblioteca crea su propia clase R.

    Cuando compilas los módulos de app dependientes, se compilan los módulos de biblioteca en un archivo AAR y, luego, se agregan al módulo de la app. Por lo tanto, cada biblioteca tiene su propia clase R cuyo nombre corresponde al nombre del paquete de la biblioteca.

    La clase R que se genera desde el módulo principal y el módulo de biblioteca se crea en todos los paquetes necesarios, incluidos el paquete principal del módulo y los paquetes de las bibliotecas.

  • Un módulo de biblioteca puede incluir su propio archivo de configuración ProGuard.

    Si tienes un proyecto de biblioteca que usas para compilar y publicar un AAR, puedes agregar un archivo de configuración de ProGuard a la configuración de compilación de la biblioteca. Si lo haces, el complemento de Android para Gradle aplicará las reglas de ProGuard que hayas especificado. Las herramientas de compilación incorporan este archivo dentro del archivo AAR generado para el módulo de biblioteca. Cuando agregas la biblioteca a un módulo de app, el archivo ProGuard de la biblioteca se anexa al archivo de configuración de ProGuard (proguard.txt) del módulo de app.

    Mediante la incorporación de un archivo ProGuard en el módulo de biblioteca, garantizas que los módulos de app que dependen de la biblioteca no tengan que actualizar manualmente los archivos ProGuard para usarla. Cuando el sistema de compilación de Android Studio compila tu app, usa las directivas del módulo de app y de la biblioteca. Por lo tanto, no es necesario ejecutar un reductor de código en la biblioteca en un paso separado.

    Para agregar las reglas de ProGuard al proyecto de biblioteca, especifica el nombre del archivo con la propiedad consumerProguardFiles dentro del bloque defaultConfig del archivo build.gradle o build.gradle.kts de la biblioteca.

    Por ejemplo, en el siguiente fragmento, se configura lib-proguard-rules.txt como archivo de configuración de ProGuard de la biblioteca:

    Groovy

    android {
        defaultConfig {
            consumerProguardFiles 'lib-proguard-rules.txt'
        }
        ...
    }

    Kotlin

    android {
        defaultConfig {
            consumerProguardFiles("lib-proguard-rules.txt")
        }
        ...
    }

    Sin embargo, si el módulo de biblioteca es parte de una compilación de varios módulos que se compila en un APK y no genera un AAR, debes ejecutar la reducción de código solo en el módulo de la app que consuma la biblioteca. Para obtener más información sobre las reglas de ProGuard y su uso, consulta Cómo reducir, ofuscar y optimizar tu app.

  • Probar un módulo de biblioteca es casi lo mismo que probar una app.

    La principal diferencia es que la biblioteca y sus dependencias se incluyen automáticamente como dependencias del APK de prueba. Esto significa que el APK de prueba incluye no solo su propio código, sino también el AAR de la biblioteca y todas sus dependencias. Debido a que no hay una app de prueba separada, la tarea androidTest instala (y desinstala) solo el APK de prueba.

    Cuando se combinan varios archivos de manifiesto, Gradle sigue el orden de prioridad predeterminado y combina el manifiesto de la biblioteca en el manifiesto principal del APK de prueba.

Anatomía de un archivo AAR

La extensión de un archivo AAR es .aar y el tipo de artefacto de Maven también es aar. El archivo en sí es un archivo ZIP. La única entrada obligatoria es /AndroidManifest.xml.

Un archivo AAR también puede incluir una o más de las siguientes entradas opcionales: