Generación dinámica de sabores de productos

He creado una aplicación de Android que debe ser construida en muchos (30 +) sabores.

Mi idea era generar los diferentes productFlavors directamente desde la estructura de carpetas en mi directorio src , ya que la configuración siempre es muy similar (básicamente sólo otro nombre de paquete, un nuevo icono de lanzador y algunas cadenas cambian).

La carpeta src este aspecto:

 └── src ├── flavor1 │  ├── flavor2.keystore │  ├── res ├── flavor2 │  ├── res │  ├── flavor2.keystore └── main  ├── AndroidManifest.xml  ├── java  └── res 

Si tuviera que crear las propiedades gradle a mano se vería de alguna manera como esto:

 android { .... productFlavors { flavor1 { packageName 'com.example.flavor1' } flavor2 { packageName 'com.example.flavor2' } } } 

Cada vez que intento cambiar la configuración de productFlavors después de su creación consigo un error o los cambios / adiciones son ignorados silenciosamente.
Esto podría ser un problema causado por mí, porque mi experiencia de Gradle / Groovy es muy limitada, o esto no es posible.

La mayoría de las GroupableProductFlavorDsl_Decorated obtienes un error, diciendo que GroupableProductFlavorDsl_Decorated no podría ser manipulado de la manera que yo quiera.

Lo que estoy tratando de archivar de alguna manera se vería así:

 android { .... def flavors = getMyFlavorsFromFileSystem() productFlavors { } flavors.each { name, config -> productFlavors[name] << config } } 

Nota: Sé que esta pregunta es básicamente un duplicado de una pregunta anterior, que tristemente nunca fue contestada. Desde Gradle es algo nuevo para el mundo de Android, espero obtener más respuestas como desde la última vez que se hizo la pregunta, porque más desarrolladores están usando Gradle ahora.

Actualizar:

Aquí algunos enfoques muy simples que he intentado:

Variante 1:

 android { productFlavors { } productFlavors['flavor1'] << { packageName "com.example.flavor1" } productFlavors['flavor2'] << { packageName "com.example.flavor2" } } /* A problem occurred evaluating root project 'MyProject'. > GroupableProductFlavorDsl with name 'flavor1' not found. */ 

Variante 2:

 android { productFlavors { } productFlavors['flavor1'] = { packageName "com.example.flavor1" } productFlavors['flavor2'] = { packageName "com.example.flavor2" } } /* no error, but does not work */ 

Variante 3:

 android { productFlavors { } productFlavors['flavor1'] = [packageName: "com.example.flavor1"] productFlavors['flavor2'] = [packageName: "com.example.flavor2"] } /* no error, but does not work */ 

Todos ellos como un Gist .

3 Solutions collect form web for “Generación dinámica de sabores de productos”

Resuelto por ensayo y error:

 android { // let's assume these are return by a function which reads the filesystem def myFlavors = [ flavor1: [ packageName: "com.example.flavor1" ], flavor2: [ packageName: "com.example.flavor2" ] ] productFlavors { myFlavors.each { name, config -> "$name" { packageName config.packageName } } } } 

Sé que ya hay una respuesta para esto, pero he combinado el acercamiento de Chris.Zou con TheHippo. Y añadir mi propio método para hacer esto.

Básicamente, cuando se trata de sabores, normalmente trabajamos con diferentes directorios en / app / src / que contiene recursos. Y como el nombre del directorio es igual al nombre del paquete, simplemente enumeré los directorios de esa carpeta (excluidos "main" y "androidTest").

Así que aquí está mi script de gradle completo, que funciona:

 def map = [:] new File("./app/src").eachFile() { file-> def fileName = file.getName() if( fileName == "main" || fileName == "androidTest") { return } map.put(fileName, 'com.mypackagename.' + fileName ) } productFlavors { map.each { flavorName, packagename -> "$flavorName" { applicationId packagename } } } 

Editar:

  • También quisiera agregar, el com.mypackagename es básicamente el path de raíz para todos los sabores.
  • Tengo un script separado que copia-pega el directorio de un sabor a la carpeta / app / src /.

Dado que el autor de la pregunta no quería compartir su código para leer los archivos. Voy a escribir sobre lo que hice. Puse todas las variantes de nombre en un archivo llamado "app / build_variants.txt", una línea para cada uno, algo así:

 flavor1 flavor2 flavor3 flavor4 flavor5 

Y en "app / build.gradle":

 //...other configs... android { productFlavors { new File('app/build_variants.txt').eachLine { "$it" { resValue "string", "build_variant_name", "$it" } } } } //...other configs 

Esto tendrá el mismo resultado que el código siguiente:

 //...other configs... android { productFlavors { flavor1 { resValue "string", "build_variant_name", "flavor1" } flavor2 { resValue "string", "build_variant_name", "flavor2" } flavor3 { resValue "string", "build_variant_name", "flavor3" } flavor4 { resValue "string", "build_variant_name", "flavor4" } flavor5 { resValue "string", "build_variant_name", "flavor5" } } } //...other configs 

La clave aquí es la línea new File('app/build_variants.txt').eachLine { "$it" { resValue "string", "build_variant_name", "$it" } } . Lee el archivo 'app / build_variants.txt' y, para cada línea, genera un sabor de producto con el nombre en la línea que se lee. el $it es la línea en la que pasa. Simplemente la sintaxis de cierre groovy. Si quieres una comprensión más profunda. Recomiendo encarecidamente ver el video de @Daniel Lew sobre groovy y gradle. ¡Es impresionante!.

  • Android Studio / gradle: redimensionamiento automático de imágenes para android
  • Error al configurar SDK: Error: Módulo 'app': plataforma 'Google Inc.: API de Google: 21' no encontrado
  • Android Robolectric Gradle - java.lang.OutOfMemoryError: PermGen espacio
  • Error de Gradle "Atributo" xxx "ya se ha definido" en Android Studio
  • Vista personalizada en una biblioteca aar local no accesible?
  • Firmar APK sin poner información de almacén de claves en build.gradle
  • ¿Hay una manera de tener una sección común con buildConfigField y resValue en gradle?
  • ¿Cómo crear una biblioteca de Android y subirla en github?
  • el ensamblaje del gradleRelease utiliza la llave / el certificado incorrectos
  • Proyecto de gradle de Android proyecto de compilación en un árbol de directorio diferente
  • Escritura del script Gradle para ejecutar casos de prueba de unidad para el proyecto Eclipse Android Test
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.