【问题标题】:Instruct Android Gradle script to delete unaligned apks and clean artifact files指示 Android Gradle 脚本删除未对齐的 apk 并清理工件文件
【发布时间】:2013-11-20 08:29:54
【问题描述】:

几天前我开始使用 Gradle 构建系统,并让脚本按我的意愿工作,这里是:

buildscript {
    repositories {
        mavenCentral()
    }
}

dependencies {
    classpath 'com.android.tools.build:gradle:0.6.+'
}

apply plugin: 'com.android.application'

android {
    compileSdkVersion 17
    buildToolsVersion '18.0.1'


    productFlavors {
        flavor1 {
            packageName "flavor1"
        }
        flavor2 {
            packageName "flavor2"
        }
        flavor3 {
            packageName "flavor3"
        }
    }

    sourceSets {
        main {
            manifest.srcFile 'AndroidManifest.xml'
            java.srcDirs = ['src']
            resources.srcDirs = ['src']
            renderscript.srcDirs = ['src']
            res.srcDirs = ['res']
            assets.srcDirs = ['assets']
        }

        signingConfigs {
            release {
                storeFile file("test.keystore")
                storePassword "*****"
                keyAlias "****"
                keyPassword "*****"
            }
        }
        buildTypes {
            release {
                signingConfig signingConfigs.release
            }
        }

    }

    dependencies {
        compile fileTree(dir: 'libs', include: '*.jar')
    }
}

正如您所见,这里没有什么特别之处,只需构建 3 种风格的应用程序并使用相同的密钥对它们进行签名。我只是运行 gradle assembleRelease 并在 20 秒后将我的 apk 放在 build 文件夹中。但问题是生成了我不想要的其他文件,例如 appname-release-unaligned.apk。

我知道在签署 apk 之前需要此文件,但想在我的 gradle 脚本中添加删除这些文件的任务?

另外,如果可能的话,我想删除在构建期间生成的所有其他(shell 我说的是人工制品文件)。本质上,我想运行类似 gradle clean 之类的东西,但保留构建 apk 文件。我该怎么做?

BONUS:如果有人对我如何优化此脚本并启用 zip align 和 proguard(没有自定义规则,只需默认混淆就可以)有指示,这也会对我有所帮助,因为我对 gradle 非常陌生,而且我没有任何教程下面解释了这些步骤。

【问题讨论】:

    标签: android build gradle


    【解决方案1】:

    2018 年 2 月更新。 使用 Android Gradle 插件 3.0 或更高版本时,此块将导致构建错误。请参阅下面的“deepSymmetry”评论。

    “修复”是完全删除块,插件的默认行为会自动清理中间临时 apk(例如:app-debug-unaligned.apk)。


    相当老的话题,但这里是删除不必要的“未对齐”文件的现代解决方案。这非常方便,尤其是在 CI 服务器上可以节省一些空间。

    很遗憾,插件没有为 'zipAlign' 任务提供挂钩,所以我们需要挂钩在 'zipAlign' 之后的 'assemble' 任务。

    适用于最新的 gradle 插件 1.2.0 (gradle-2.4) 但应该对 1.+ 有效

    // delete unaligned files
    android.applicationVariants.all { variant ->
      variant.assemble.doLast {
        variant.outputs.each { output ->
            println "aligned " + output.outputFile
            println "unaligned " + output.packageApplication.outputFile
    
            File unaligned = output.packageApplication.outputFile;
            File aligned = output.outputFile
            if (!unaligned.getName().equalsIgnoreCase(aligned.getName())) {
                println "deleting " + unaligned.getName()
                unaligned.delete()
            }
        }
      }
    }
    

    如果您更喜欢检查 zipAlignEnable 标志,还有另一个,但在这种情况下,您将被绑定到文件名中的“未对齐”常量,因为发布版本使用 zipAlignEnabled=true 并且没有signingConfig 跳过“zipAlign”任务并只生成一个文件: 'app-release-unsigned.apk'。

    // delete unaligned files
    android.applicationVariants.all { variant ->
    variant.assemble.doLast {
        variant.outputs.each { output ->
            println "aligned " + output.outputFile
            println "unaligned " + output.packageApplication.outputFile
    
            File file = output.packageApplication.outputFile;
            if (variant.buildType.zipAlignEnabled && file.getName().contains("unaligned")) {
                println "deleting " + file.getName()
                file.delete()
            }
        }
      }
    }
    

    我使用第一个以防万一。

    【讨论】:

    • 感谢您提供的信息。这似乎是处理这个问题的好方法。我会测试一下。
    • 欢迎。与我的解决方案中当前接受的答案不同,我们不需要特殊任务,也不必在任何地方复制文件。
    • 仍然可以正常工作(也适用于 gradle 插件 2.2.0)。使用第一个选项。
    • 使用 Gradle 3.0.0,它会引发错误。 Could not get unknown property 'outputFile' for task ':app:SomeTask' of type com.android.build.gradle.tasks.PackageApplication. 迁移指南谈论 manifestOutputFile 但不是这个。
    • 原来删除未对齐的apks默认包含在android 3.0 gradle插件中,所以如果您正在将项目迁移到新插件(就像我现在一样),只需删除此块并你仍然不会有任何未对齐的 apk - 耶 =)
    【解决方案2】:

    我注意到这个问题不时有一些活动,所以如果它对某人有帮助,这就是我解决问题的方法。只需定义新任务来复制文件,然后设置执行顺序。

    task copyTask(type: Copy) {
       from 'build/apk'
       into 'apks'
       exclude '**/*-unaligned.apk'
    }
    
    task allTask(dependsOn: ['clean', 'assembleRelease', 'copyTask']){
        clean.mustRunAfter copyTask
        copyTask.mustRunAfter assembleRelease
    }
    

    然后,当您想要进行构建时,只需调用这个 allTask​​。

    【讨论】:

      【解决方案3】:

      我至少可以回答你的奖金问题:

      buildTypes {
          release {
              runProguard true
              signingConfig signingConfigs.release
          }
      }
      

      如果您有特定的 proguard 规则,只需将此行输入您的 defaultConfig 或您的产品风格:

      proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt'
      

      第一个 proguard 规则是来自您的 Android SDK 的通用规则,第二个来自您的模块目录。

      如果您使用构建变体 release 构建项目,则默认启用 ZipAlign。

      【讨论】:

      • 感谢您的回复。 proguard 部分很有帮助。你能告诉我规则txt应该和eclipse放在同一个地方吗?请注意,我通过创建调用 build 的 bat 脚本解决了上述问题,而不是将 apk 移出而不是调用 clean,但我仍然坚持如何在 gradle 中执行此操作。
      • 如果没有提供具体路径而只提供了普通文件名,proguard-rules.txt 是基于模块的目录(build.gradle 所在的位置。但一般来说,你可以把这个文件在你想要的地方。此外,如果使用 Android Studio / Gradle,你有不同的项目结构,所以或多或少没有任何东西留在同一个目录中。只需创建一个空的新项目,你很快就会得到它。
      【解决方案4】:

      来自@PSIXO 的答案稍作修改,考虑到 Android Studio 1.5,运行测试用例并重命名 apk 文件以实现更好的 CI 集成:

      android {
        compileSdkVersion 23
        buildToolsVersion "23.0.2"
      
        defaultConfig {
              applicationId "com.mydemoci"
              minSdkVersion 14
              targetSdkVersion 23
              versionCode 1
              versionName "1.0"
              archivesBaseName = "$applicationId-v$versionName"
          }
      }
      
      task copyOutputApk(type: Copy) {
          from 'build/outputs/apk'
          into 'apk'
          exclude '**/*-unaligned.apk'
      }
      
      task buildTestDebug(dependsOn: ['clean', 'assembleDebug', 'check', 'copyOutputApk']) {
          check.mustRunAfter assembleDebug
          copyOutputApk.mustRunAfter check
          clean.mustRunAfter copyOutputApk
      }
      

      开始构建运行gradlew buildTestDebug

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多