16

几天前我开始使用 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 文件。我该怎么做呢?

奖励:如果有人有关于如何优化此脚本并启用 zip align 和 proguard(没有自定义规则,只是默认混淆是可以的)的指针,这也会对我有所帮助,因为我对 gradle 非常陌生,而且我遵循的教程都没有解释这些脚步。

4

4 回答 4

21

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-释放-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()
        }
    }
  }
}

我正在使用第一个以防万一。

于 2015-06-14T04:56:05.700 回答
9

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

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​​ 。

于 2014-07-23T12:32:37.327 回答
1

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

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

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

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

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

如果您使用 build variant 构建项目,则默认启用 ZipAlign release

于 2014-02-10T09:15:01.817 回答
0

来自@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

于 2015-12-03T12:27:37.620 回答