Variables de entorno en Android nativo

23-05-2022

Por Mireia Scholz, José Ángel Nieda Hernández

Como comentamos en el anterior post, una de las apps que estamos desarrollando es una aplicación nativa para Android que se comunica con varios backends (también nuestros).

En el día a día, constantemente estamos cambiando entre las URLs de nuestras máquinas de desarrollo y las URLs de las máquinas en la red de nuestro cliente.

En el desarrollo nativo de aplicaciones para Android, las variables de entorno no se gestionan exactamente igual que en otros entornos. No se gestionan con un fichero .env ni desde el IDE, existen soluciones con librerías externas que nos dan la posibilidad de leer directamente desde ficheros .env nuestras variables.

Sin embargo, para evitar usar librerías externas y aprovechar las opciones que Android nos da por defecto para configurar las variables de entorno de nuestro proyecto, implementamos la solución que les vamos a contar en este post 🙂.


BuildTypes y campos personalizados 🤯

Al principio, solamente teníamos que cambiar las URLs entre local y preproducción en momentos puntuales, por ejemplo cuando teníamos que hacer una demo y realmente no nos suponía un problema. Sin embargo, ahora estamos en una fase que requiere pruebas en ambos entornos; así que cambiar cada vez las URLs una a una ya no es viable.

Android permite generar distintos tipos de build (buildTypes) a la hora de compilar nuestro proyecto. Por defecto tenemos debug (el que correrá por defecto en el emulador) y release, pero podemos añadir los que queramos. Cada uno de los buildTypes (build variants) puede contener una configuración especifica; por ejemplo, si se podrá debuggear o no, habilitar los reportes de coverage, etc.

Lo que realmente nos interesa es que podemos añadir campos personalizados (buildConfigFields) para cada build que podemos acceder desde la app. Vamos, variables de entorno de toda la vida. Esto está explicado con más detalle en la documentación de Android:

"En el tiempo de compilación, Gradle genera la clase BuildConfig de modo que el código de tu app pueda explorar información sobre la compilación actual. También puedes agregar campos personalizados a la clase BuildConfig desde tu archivo de configuración de la compilación de Gradle usando el método buildConfigField() y acceder a esos valores en el código del tiempo de ejecución de tu app(....)"

Estos campos personalizados parece que podrían solucionar nuestro problema 🙉

Ejemplo práctico ✨

Vamos a crear un simple proyecto donde mostramos un saludo a distintas personas basándonos en una variable de entorno USERNAME ¡AL TURRÓN! 👷‍♀️👷‍♂️

1. Crear un nuevo proyecto

Creamos un nuevo proyecto con Android Studio y con la plantilla EmptyActivity, que es más que suficiente para este ejemplo.

2. Crear 2 BuildTypes

Creamos 2 nuevos build types "exampleJose" y "exampleMireia" desde el menú superior haciendo click en Build > Edit Built Type... y después en el botón de añadir.

Es importante setear el valor SigningConfig para que nuestra aplicación se pueda ejecutar en el emulador. La configuración de ambos BuildTypes quedaría de la siguiente manera:

Imagen crear 2 Builtypes

3. Añadir el campo personalizado

En el build.gradle de la aplicación podremos ver los nuevos buildTypes que acabamos de añadir. Ahora les añadiremos un campo personalizado USERNAME con valores diferentes utilizando BuildConfigField en cada uno:

Imagen añadir el campo personalizado

4. Utilizar la nueva variable

Podemos acceder al valor que acabamos de la siguiente manera: BuildConfig.USERNAME . En este ejemplo, lo escribiremos en un TextView. Es posible que el IDE aun no lo autocomplete si no hemos compilado el proyecto aún (BuildConfig.java aun no existe)

Imagen utilizar la nueva variable

5. Elegir un buildType

Para cambiar de buildType a la hora de lanzar la app, debemos seleccionar en el menú de Android Studio Build > Select Build Variant y se mostrará un menú con los distintos BuildTypes disponibles:

Imagen elegir un buildType

Si compilamos la aplicación con el BuildType exampleJose, el aspecto del fichero BuildConfig.java que se genera es el siguiente, con el valor que tiene la variable USERNAME en el BuildType seleccionado (JOSE):

Imagen elegir un buildType parte II

6. Cambiar de Build Variant

Para cambiar de buildType volvemos al menú de Select Build Variant

Imagen cambiar de Build Variant

Resultado

Si ejecutamos la aplicación en el emulador, este sería el resultado final en nuestra app con los dos buildTypes que acabamos de configurar:

Imagen resultado 1 Imagen resultado 2

Nota: Como no añadimos el valor de la variable USERNAME en el BuildType de release, tendremos un error de compilación si tratamos de compilar la aplicación en este modo.


Conclusión

Los BuildTypes y BuildConfigFields aportan flexibilidad y claridad a nuestro código, actuando como variables de entorno para Android sin necesidad de utilizar dependencias adicionales.

En nuestro proyecto Android, podemos crear diferentes BuildTypes para cada entorno (en nuestro caso local y preproducción). Cada uno tendria las URL de los endpoints correspondientes en forma de campos personalizados (BuildConfigFields) que serán accesibles desde el código de la aplicación ✨


Bibliografía