studio - flavors android gradle
Uso de Build Flavors: estructuración de carpetas de origen y build.gradle correctamente (6)
Algo que es importante y me ha bloqueado durante bastante tiempo es que el nombre del sabor que debe coincidir con el paquete en lugar del paquete definido dentro de la definición de sabor en gradle. Por ejemplo:
src/flavor1/java/com/foo/A.java
coincidirá
productFlavors {
flavor1 {
packageName ''com.android.studio.test.foobar''
}
}
pero
src/foobar/java/com/foo/A.java
no se usará para la compilación flavor1.
Tenga en cuenta: Respuesta editada después de la respuesta de Xavier
Intento utilizar Build Flavors diferentes para un mismo proyecto de aplicación en Android Studio. Sin embargo, parece que me está costando trabajo configurarlo para que funcione correctamente.
Pasos:
- Crea un nuevo Android Studio Project, llamado ''Test''.
Abra build.gradle * y agregue las siguientes líneas:
productFlavors { flavor1 { packageName ''com.android.studio.test.flavor1'' } flavor2 { packageName ''com.android.studio.test.flavor2'' } }
- Después de reiniciar Android Studio, ahora veo 4 variantes de compilación en la sección Construir variantes. Lo que significa que fuimos exitosos en preparar los sabores del producto hasta el momento. **
Creó una nueva carpeta de Origen para flavor1 ; sin embargo, no estoy seguro si lo estoy haciendo de la manera correcta. Así es como lo hice:
- Tenga en cuenta que el nombre de mi paquete para este proyecto es:
com.foo.test
- Haga clic derecho en la carpeta
src
, para flavor1, realmente creé las carpetas individuales en el explorador, de forma que la estructura seasrc/flavor1/java/com/foo/test/MainActivity.java
. - Lo anterior funcionó bien, ya que la carpeta ''java'' está en azul , lo que significa que el IDE sabe que es un directorio de origen activo. Además, el paquete se creó automáticamente. A pesar de esto, recibo una advertencia para la clase duplicada encontrada. Ver captura de pantalla aquí.
- Para flavor2, traté de crear el paquete manualmente, pero la carpeta ''src'' para flavor2 parece no estar en azul, y por lo tanto las opciones son diferentes cuando hago clic derecho, y ''New Package'' no está disponible para mi uso. Ver imagen aquí.
- Tenga en cuenta que para flavor1, también creé un directorio ''res'', que se vuelve azul, pero a pesar de eso, no ofrece la capacidad de crear un archivo de recursos de Android o un directorio de recursos Andorid, en caso de que desee utilizar diferentes resorciones para diferentes sabores.
- Tenga en cuenta que el nombre de mi paquete para este proyecto es:
¿Estoy haciendo algo mal? ¿O me estoy perdiendo algo? Hágame saber si necesita más información.
* Mi proyecto parece tener dos archivos build.gradle. Uno ubicado en la raíz de la carpeta del proyecto (/ GradleTest), este está vacío. El segundo ubicado en la raíz de una subcarpeta de / GradleTest, también llamado ''GradleTest'' (GradleTest-GradleTest), este es el que ya tenía código cuando se abrió; por lo tanto, ese es el que edité.
** Comprobé la configuración de gradle y, al parecer, el uso de Auto- Import ya estaba habilitado. A pesar de esto, realizar cambios en el archivo build.gradle no actualiza automáticamente las variantes de compilación. Nota: También intenté usar Build - Rebuild Project, y / o Build - Make Project, no go. Todavía tengo que cerrar el proyecto y volver a abrir para que los cambios entren en vigencia.
Parece que necesita volver a cargar su proyecto después de agregar nuevos sabores en build.gradle
. Después de eso, verá 4 Variantes de compilación en la vista Variantes de compilación (puede acceder desde el borde izquierdo de la ventana).
En cuanto a los directorios fuente adicionales, parece que necesita crearlos a mano: src/flavor1/java
y src/flavor2/java
. Verá que cambiar el sabor en la vista "Variantes de compilación" cambiará los directorios de origen actualmente activos (el directorio es azul cuando es un directorio de origen activo )
Finalmente, "gradle creará nuevos conjuntos de origen para sus nuevos sabores" significa que gradle creará los objetos android.sourceSets.flavor1
y android.sourceSets.flavor2
y podrá usarlos en su script build.gradle. Pero esos objetos se crean dinámicamente, es por eso que no los ve en build.gradle
(sugiero que lea esto: http://www.gradle.org/docs/current/userguide/tutorial_using_tasks.html Especialmente el 6.6: explica la creación de tareas dinámicas. Un script de Gradle es un script maravilloso, así que sugiero que te familiarices con Groovy también)
Si ingresó en las preferencias de Studio, en la sección Gradle, puede habilitar la importación automática para su proyecto (lo habilitaremos de manera predeterminada más adelante). Esto le permitirá a Studio volver a importar su build.gradle cada vez que la edite.
Crear sabores no significa que vas a usar un código personalizado para ellos, así que no creamos las carpetas. Necesitas crearlos tú mismo.
Si miras mi charla de IO , verás cómo mezclamos los valores de los sabores y el tipo de compilación para crear la variante.
Para la fuente de Java:
src/main/java
src/flavor1/java
src/debug/java
son los 3 usados para crear una salida única. Esto significa que no pueden definir la misma clase.
Si desea tener una versión diferente de la misma clase en los dos sabores, deberá crearla en ambos sabores.
src/flavor1/java/com/foo/A.java
src/flavor2/java/com/foo/A.java
Y luego tu código en src / main / java puede hacer
import com.foo.A
dependiendo del sabor seleccionado, se usa la versión correcta de com.foo.A.
Esto también significa que ambas versiones de A deben tener la misma API (al menos cuando se trata de la API utilizada por las clases en src / main / java / ...
Editar para hacer coincidir la pregunta revisada
Además, es importante poner la misma clase A solo en carpetas de origen que son mutuamente excluyentes. En este caso src / flavor1 / java y src / flavor2 / java nunca se seleccionan juntos, pero main y flavor1 son.
Si desea proporcionar una versión diferente de una actividad con un sabor diferente, no lo coloque en src / main / java.
Tenga en cuenta que si tenía 3 sabores y solo quería uno personalizado para flavor1, mientras que flavor2 y flavor3 compartían la misma actividad, podía crear carpetas de origen comunes para esas otras dos actividades. Tiene total flexibilidad para crear nuevas carpetas de origen y configurar el conjunto de origen para usarlas.
En tus otros puntos:
Es normal que la segunda carpeta fuente de sabor no sea azul. Debes cambiar al segundo sabor para habilitarlo, y luego podrás crear paquetes y clases dentro. Hasta entonces, Studio no considera que sea una carpeta de origen. Esperemos que esto mejore en el futuro para que el IDE conozca esas carpetas fuente inactivas .
Creo que también es normal que no puedas crear archivos de recursos en la carpeta res. El sistema de menú no se ha actualizado para tratar con todas estas carpetas de recursos adicionales. Esto vendrá después.
Tuve el mismo problema cuando migré mi proyecto a Gradle. El problema fue que la compilación no encontró la carpeta de recursos adecuada. Lo arreglé agregando esto debajo del elemento de Android en build.gradle:
sourceSets {
main {
res.srcDirs = [''myProject/res'']
}
}
"Sabores de producto" en Android
A veces me han preguntado cómo trabajar con diferentes hosts, iconos o incluso nombres de paquetes, dependiendo de las diferentes versiones de la misma aplicación.
Hay muchas razones para hacer esto y una manera fácil de hacerlo: sabores de productos.
Puede definir en su script build.gradle este tipo de cosas que he descrito anteriormente.
Sabores del producto Parte de este artículo está escrito pensando en los sabores de los productos, entonces, ¿qué son? En cuanto a la documentación de Android:
El sabor de un producto define una versión personalizada de la aplicación creada por el proyecto. Un solo proyecto puede tener diferentes sabores que cambian la aplicación generada.
¿Cómo puedes definirlos? Debes escribir en tu build.gradle qué sabores quieres definir:
productFlavors {
...
devel {
...
}
prod {
...
}
}
Ahora, tendremos dos sabores diferentes de nuestra aplicación. También puedes verificarlo en Android Studio dentro de la pestaña Variedades de compilación
Variantes de compilación
Múltiples nombres de paquetes
¿Qué sucede si desea tener instalada en su teléfono una aplicación con estado de desarrollo y otra para el estado de producción? Como sabrá, solo puede instalar una aplicación con el mismo nombre de paquete (si intenta instalar alguna APK nueva con la misma que está instalada en su teléfono, intentará actualizarla).
Lo único que debe hacer es definirlo en cada uno de los sabores de su producto:
android {
productFlavors {
devel {
applicationId "zuul.com.android.devel"
}
prod {
applicationId "zuul.com.android"
}
}
}
Envíe solicitudes a múltiples hosts según el sabor Como antes, debe incluir algunos parámetros en el campo de configuración de sabor de su producto.
android {
productFlavors {
devel {
applicationId "zuul.com.android.devel"
buildConfigField ''String'', ''HOST'', ''"http://192.168.1.34:3000"''
}
prod {
applicationId "zuul.com.android"
buildConfigField ''String'', ''HOST'', ''"http://api.zuul.com"''
}
}
}
A modo de ejemplo, trataremos de mostrarle cómo puede integrar esto con Retrofit para enviar solicitudes al servidor adecuado sin controlar a qué servidor está apuntando y en función del sabor. En este caso, este es un extracto de la aplicación de Android Zuul:
public class RetrofitModule {
public ZuulService getRestAdapter() {
RestAdapter restAdapter = new RestAdapter.Builder()
.setEndpoint(BuildConfig.HOST)
.setLogLevel(RestAdapter.LogLevel.FULL)
.build();
return restAdapter.create(ZuulService.class);
}
}
Como puede ver, solo tiene que usar BuildConfigclass para acceder a la variable que acaba de definir.
Cualquier variable disponible a través de su código La variable HOST no es la única que puede exponer en su código. Puedes hacerlo con lo que quieras:
prod {
applicationId "zuul.com.android"
buildConfigField ''String'', ''HOST'', ''"http://api.zuul.com"''
buildConfigField ''String'', ''FLAVOR'', ''"prod"''
buildConfigField "boolean", "REPORT_CRASHES", "true"
}
Puede acceder a ellos de la siguiente manera:
BuildConfig.HOST
BuildConfig.FLAVOR
BuildConfig.REPORT_CRASHES
Diferentes íconos por sabor Si quieres tener diferentes íconos por sabor, para que puedas detectar visualmente cuál abres (también puedes hacerlo por el nombre ... ¡pero no cabía en el espacio!), Solo tienes para definir nuevas estructuras de directorios para cada uno de los sabores.
En el ejemplo que acabo de usar, hay dos sabores: desarrollo y prod. Entonces, podríamos definir dos nuevas estructuras de directorio para que podamos definir los recursos que queremos:
estructura
Esto funciona con otros tipos de recursos como strings.xml, integers.xml, arrays.xml
, etc.
Configurar la configuración de firma
Para configurar manualmente las configuraciones de firma para su tipo de compilación de lanzamiento usando las configuraciones de compilación de Gradle:
1.Crear un almacén de claves. Un keystore es un archivo binario que contiene un conjunto de claves privadas. Debe mantener su almacén de claves en un lugar seguro. 2. Crea una clave privada. Una clave privada representa la entidad que se identificará con la aplicación, como una persona o una empresa. 3.Agregue la configuración de firma al archivo build.gradle de nivel de módulo:
android {
...
defaultConfig {...}
signingConfigs {
release {
storeFile file("myreleasekey.keystore")
storePassword "password"
keyAlias "MyReleaseKey"
keyPassword "password"
}
}
buildTypes {
release {
...
signingConfig signingConfigs.release
}
}
}
Genera una APK firmada:
Para generar una APK firmada, seleccione Generar> Generar APK firmado en el menú principal. El paquete en la aplicación / build / apk / app-release.apk ahora está firmado con su clave de lanzamiento.
En gradle:
Para los tipos de compilación solo necesita:
buildTypes {
release{
//proguard, signing etc.
}
debug {
//development
}
}
}
Y luego para los sabores agregas los que necesitas
productFlavors {
pro {
applicationIdSuffix ''.paid''
buildConfigField ''boolean'', ''PRO'', ''true''
}
free {
applicationIdSuffix ''.free''
buildConfigField ''boolean'', ''PRO'', ''false''
}
}