Android Product Flavors

En muchas ocasiones, cuando desarrollemos una app de Android, nos interesará generar diferentes variantes de una misma app. Por ejemplo, en el caso de nuestra aplicación deba consumir uno json proporcionado por un servicio en la red, tendrémos un servidor para pruebas y un servidor de producción.

Para ello usamos Product Flavors, una funcionalidad del sistema de construcción Gradle de Android.

En el fichero build.gradle de nuestra app añadiremos:

	productFlavors {
		
		dev {
			applicationId "com.sourcerebels.flavors.dev"
			resValue "string", "service_url", "http://dev.example.com"
		}
		production {
			applicationId "com.sourcerebels.flavors.production"
			resValue "string", "service_url", "http://www.example.com"
		}
	}

Ahora, desde la ventana “Build Variants” de Android Studio, seleccionaremos que variante queremos construir.

Tambíen podemos hacerlo con gradle desde la línea de comandos. Por ejemplo:

	gradle module:assembleDevDebug
	gradle module:assembleProductionRelease

Flavors nos permite además personalizar recursos o assets. Para ello es tan simple como crear las carpetas src/flavor/res, src/flavor/assets y src/flavor/java.

Por ejemplo, si quisiesemos personalizar los colores o un recurso de la app en función de la variante, personalizaríamos los siguientes ficheros:

	src/dev/res/values/colors.xml
	src/dev/res/drawable/some_resource.xml

	src/production/res/values/colors.xml
	src/production/res/drawable/some_resource.xml

Parece que vamos a usar mucho esta funcionalidad de ahora en adelante.

Detección contexto de test

A veces, necesitamos diferenciar si estamos ejecutando nuestro código con normalidad o, por contra, nos encontramos en un contexto de test automatizados.

Supuestamente existe un método isRunningInTestHarness para hacer esto mismo, aunque en mi experiencia no funciona.

Una alternativa posible para hacer esto sería aprovecharnos de la estructura de proyecto que propone el sistema de construcción Gradle y los recursos de Android.

Para ello, en el directorio src/main/res/values/ crearíamos un fichero xml de recursos de Android (p.ej: configuration.xml) con un boolean a false:

<bool android:name="running_in_test_harness">false</bool>

También en el directorio src/androidTest/res/values/ crearemos el mismo fichero configuration.xml con el mismo boolean pero esta vez con valor true.

<bool android:name="running_in_test_harness">true</bool>

Posteriormente podemos obtener el valor de la siguiente manera:

public static boolean isRunningInTestHarness(Context context) {
	return context.getResources().getBool(R.bool.running_in_test_harness);
}