Estoy tratando de agregar una tarea personalizada para mi Android del proyecto build.gradle para copiar el final APK y Proguard del mapping.txt en un directorio diferente. Mi tarea depende de la assembleDevDebug tarea:

task publish(dependsOn: 'assembleDevDebug') << {
    description 'Copies the final APK to the release directory.'

    ...
}

Puedo ver cómo hacer una copia del archivo utilizando el estándar de Copy tipo de tarea, como por la documentación:

task(copy, type: Copy) {
    from(file('srcDir'))
    into(buildDir)
}

pero que se supone que conoce el nombre y la ubicación del archivo que desea copiar.

¿Cómo puedo encontrar el nombre exacto y la ubicación del archivo APK, que fue construido como parte de la assembleDevDebug tarea? Es esta disponible como una propiedad? Se siente como si yo debería ser capaz de declarar los archivos como entradas para mi tarea, y declarar como salidas de la assemble tarea, pero mi Gradle-fu no es lo suficientemente fuerte.

Tengo algo de lógica personalizada para inyectar el número de versión en el nombre de archivo APK, así que mi publish tarea no puede simplemente asumir el nombre y la ubicación predeterminados.

  • ¿Has probado a usar variante.packageApplication.outputFile como se describe aquí stackoverflow.com/questions/18534313/… ?
  • ¿Qué pasaría si se reemplaza la línea con «de assembleDevDebug»
  • Esta «lógica personalizada para inyectar el número de versión en el APK del archivo de nombre», ¿te importaría compartir eso? Yo lo quiero, pero mi Gradle-fu es débil así 🙂

6 Comentarios

  1. 27

    Si usted puede conseguir la variante de objeto asociado con devDebug puede consultar con getOutputFile().

    Así que si usted quería publicar todas las variantes que había algo como esto:

    def publish = project.tasks.create("publishAll")
    android.applicationVariants.all { variant ->
      def task = project.tasks.create("publish${variant.name}Apk", Copy)
      task.from(variant.outputFile)
      task.into(buildDir)
    
      task.dependsOn variant.assemble
      publish.dependsOn task
    }

    Ahora usted puede llamar a gradle publishAll y voy a publicar todas las variantes.

    Un problema con el archivo de asignación es que el Proguard tarea no darle un getter para la ubicación del archivo, por lo que actualmente no se puede realizar una consulta. Estoy esperando que esta fijo.

    • Puedo obtener Error:(270, 0) Could not find property 'outputFile' on com.and[email protected]4be85d24.
    • relpace :variant.outputs[0].outputFile
    • Esto ya no funciona porque variante.outputFile está en desuso como de gradle 3.0.0-a3 – salida en el gradle consola es: «Causa: getMainOutputFile ya no es compatible.» Se sabe de una solución?
    • Para obtener el archivo de salida de trabajo de la envoltura additionnaly applicationVariants.all { variant -> variant.outputs.all { output ->
  2. 9

    El código siguiente es lo que yo estoy usando para archivo apk y proguard de asignación en un archivo zip para cada variante con la «liberación» de tipo de generación:

    def releasePath = file("${rootDir}/archive/${project.name}")
    def releaseTask = tasks.create(name: 'release') {
    group 'Build'
    description "Assembles and archives all Release builds"
    }
    android.applicationVariants.all { variant ->
    if (variant.buildType.name == 'release') {
    def build = variant.name.capitalize()
    def releaseBuildTask = tasks.create(name: "release${build}", type: Zip) {
    group 'Build'
    description "Assembles and archives apk and its proguard mapping for the $build build"
    destinationDir releasePath
    baseName variant.packageName
    if (!variant.buildType.packageNameSuffix) {
    appendix variant.buildType.name
    }
    if (variant.versionName) {
    version "${variant.versionName}_${variant.versionCode}"
    } else {
    version "$variant.versionCode"
    }
    def archiveBaseName = archiveName.replaceFirst(/\.${extension}$/, '')
    from(variant.outputFile.path) {
    rename '.*', "${archiveBaseName}.apk"
    }
    if (variant.buildType.runProguard) {
    from(variant.processResources.proguardOutputFile.parent) {
    include 'mapping.txt'
    rename '(.*)', "${archiveBaseName}-proguard_\$1"
    }
    }
    }
    releaseBuildTask.dependsOn variant.assemble
    variant.productFlavors.each { flavor ->
    def flavorName = flavor.name.capitalize()
    def releaseFlavorTaskName = "release${flavorName}"
    def releaseFlavorTask
    if (tasks.findByName(releaseFlavorTaskName)) {
    releaseFlavorTask = tasks[releaseFlavorTaskName]
    } else {
    releaseFlavorTask = tasks.create(name: releaseFlavorTaskName) {
    group 'Build'
    description "Assembles and archives all Release builds for flavor $flavorName"
    }
    releaseTask.dependsOn releaseFlavorTask
    }
    releaseFlavorTask.dependsOn releaseBuildTask
    }
    }
    }

    Crea tareas como las siguientes:

    • liberación – Ensambla y archivos de todas las versiones de Lanzamiento
    • releaseFree – Ensambla y archivos de todas las versiones de Lanzamiento para el sabor Gratis
    • releaseFreeRelease – Ensambla y los archivos apk y su proguard asignación para el FreeRelease construir
    • releasePaid – Ensambla y archivos de todas las versiones de Lanzamiento para el sabor Pagado
    • releasePaidRelease – Ensambla y los archivos apk y su proguard asignación para el PaidRelease construir

    Contenido de archive/projectName/packageName-buildType-versionName_versionCode.zip sería:

    • packageName-buildType-versionName_versionCode.apk
    • packageName-buildType-versionName_versionCode-proguard_mapping.txt
    • Esto no parece funcionar cuando se trata de copiar el archivo de asignación en el zip. la variante.processResources.proguardOutputFile.padre regrese al intermedios/proguard carpeta que no contiene la mapping.txt archivo.
    • es lo que usted necesita en su lugar
    • He modificado el código un poco, a la salida el nombre del archivo durante la construcción. Pero lo extraño es que cuando hago clic en Build -> Generar Firmado APK, en la Gradle Consola puedo ver el nombre de archivo del archivo, pero el archivo no se ha creado o algo. Cuál es más es que el apk no se añade al archivo. Verificación de mi generación.gradle aquí: pastebin.com/Y8berupv. Gracias!
    • Me gusta el concepto, pero muchos de los campos (packageName, por ejemplo) no parece estar presente en la última versión beta de COMO.
  3. 6

    Esto es cómo puedo copiar mappings.txt siempre proguard ejecuta

    tasks.whenTaskAdded { task ->
    if (task.name.startsWith("proguard")) {//copy proguard mappings
    task << {
    copy {
    from buildDir.getPath() + "/proguard"
    into '../proguard'
    include '**/mapping.txt'
    }
    println "PROGUARD FILES COPIED"
    }
    } 
    }
  4. 6

    Tengo algunos buenos consejos aquí, pero también tenía un tiempo difícil para hacer como yo quería. Aquí está mi versión final:

    def archiveBuildTypes = ["distribute"];
    def archiveFlavors = ["googleplay"]
    android.applicationVariants.all { variant ->
    if (variant.buildType.name in archiveBuildTypes) {
    variant.productFlavors.each { flavor ->
    if (flavor.name in archiveFlavors) {
    def taskSuffix = variant.name.capitalize()
    def version = "${android.defaultConfig.versionCode} (${android.defaultConfig.versionName})" //assumes that versionName was especified here instead of AndroidManifest.xml
    def destination = "${rootDir}/${project.name}/archive/${version}"
    def assembleTaskName = "assemble${taskSuffix}"
    if (tasks.findByName(assembleTaskName)) {
    def copyAPKTask = tasks.create(name: "archive${taskSuffix}", type:org.gradle.api.tasks.Copy) {
    description "Archive/copy APK and mappings.txt to a versioned folder."
    from ("${buildDir}") {
    include "**/proguard/${flavor.name}/${variant.buildType.name}/mapping.txt"
    include "**/apk/${variant.outputFile.name}"
    }
    into destination
    eachFile { file->
    file.path = file.name //so we have a "flat" copy
    }
    includeEmptyDirs = false
    }
    tasks[assembleTaskName].finalizedBy = [copyAPKTask]
    }
    }
    }
    }
    }
    • Este es el tipo de trabajo para mí, cuando hago clic en el icono ejecutar en Android Studio, hace la tarea y en copiar algo. Cuando hago clic en Generar Firmado apk, hace la tarea, pero no hay nada copiado.
    • ‘.finalizedBy no es para mí ‘.dependsOn’ no (Ninguna explicación ATOW)
  5. 4
    def publish = project.tasks.create("publishAll")//publish all task
    applicationVariants.all { variant ->
    if (variant.buildType.name.equals("release")) {//Only Release  
    File outDir = file("//192.168.4.11/Android/Release")
    File apkFile = variant.outputs[0].outputFile
    File mapFile = variant.mappingFile
    def task = project.tasks.create("publish${variant.name.capitalize()}Apk", Copy)
    task.from apkFile, mapFile
    task.into outDir
    task.rename "mapping.txt", "${apkFile.name.substring(0, apkFile.name.length() - 3)}mapping.txt"//Rename mapping.txt
    task.doLast{
    println ">>>publish ${variant.name} success!" +
    "\ndir: ${outDir}" +
    "\napk: ${apkFile.name}"
    }
    task.dependsOn variant.assemble
    publish.dependsOn task
    }
    }
  6. 0

    Generalmente el android plugin va a poner el apk de la APP/build/apk directorio.

    Así, ejecutar assembleDebug luego ls APP/build/apk y usted debería ver:

    • APP-debug-no alineados.apk
    • APP-liberación-sin alinear.apk
    • APP-liberación-sin firmar.apk
    • APP de liberación.apk
      etc
    • Gracias, pero yo tenía la esperanza de evitar cualquier codificado supuestos como este. Realmente me gustaría una forma de obtener el nombre de archivo desde dentro de la secuencia de comandos de compilación.
    • realmente no es una suposición, de por sí, porque gradle tiene la «convención sobre configuración» de la filosofía, así que a menos que decida cambiar algo en la construcción de secuencias de comandos que no es probable que cambie. Pero yo veo tu punto y estoy de acuerdo que una variable como UNSIGNED_DEBUG_APK sería bueno. ¿Has pensado acerca de la escritura de un error o defecto,etc para android plugin equipo?

Dejar respuesta

Please enter your comment!
Please enter your name here