tag studio log example android gradle android-gradle

studio - log android



Generando dinámicamente sabores de producto. (3)

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

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 siguiente código:

//...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 de 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 lee. el $it es la línea por la que pasa. Simplemente la sintaxis de cierre de groovy. Si quieres una comprensión más profunda. Recomiendo encarecidamente ver el video de @Daniel Lew sobre groovy y gradle. ¡Es impresionante!.

He creado una aplicación para Android que debe compilarse en muchos (30+) sabores.

Mi idea fue generar los diferentes productFlavors directamente desde la estructura de la carpeta en mi directorio src , ya que la configuración siempre es muy similar (básicamente, solo otro nombre de paquete, un nuevo icono de iniciador y algunas cadenas de cambios).

La carpeta src ve así:

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

Si tuviera que crear las propiedades de gradle a mano, se vería así:

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, recibo un error o los cambios / adiciones se ignoran silenciosamente.
Este podría ser un problema causado por mí, porque mi experiencia con Gradle / Groovy es muy limitada, o esto no es posible.

Principalmente me sale un error, diciendo que GroupableProductFlavorDsl_Decorated no se puede manipular de la forma que quiero.

Lo que estoy tratando de archivar debería tener este aspecto:

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

Nota: Sé que esta pregunta es básicamente un duplicate de una pregunta anterior, que lamentablemente nunca fue respondida. Dado que Gradle es algo nuevo en el mundo de Android, espero obtener más respuestas ya que desde la última vez que se hizo la pregunta, ya que más desarrolladores están usando Gradle ahora.

Actualizar:

Aquí algunos enfoques muy simples que probé:

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 una Gist .


Resuelto por prueba 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 combiné el enfoque de Chris.Zou con TheHippo. Y añadir mi propio método para hacer esto.

Básicamente, cuando tratamos con 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 debajo de esa carpeta (excluyendo "main" y "androidTest").

Así que aquí está mi script completo de Gradle:

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 me gustaría agregar, el com.mypackagename es básicamente la ruta raíz para todos los sabores.
  • Tengo una secuencia de comandos separada que copia y pega el directorio de un sabor en la carpeta / app / src /.