【问题标题】:Android Gradle Plugin 3.0 Output apk to different directoryAndroid Gradle Plugin 3.0 将 apk 输出到不同的目录
【发布时间】:2017-12-07 21:40:38
【问题描述】:

我最近升级到 Gradle 3.0,现在发现重命名输出 APK 的功能发生了变化。我想我可以解决这个问题,但我想知道我是否仍然可以为 APK 选择目标目录。我们现有的软件使用了我想要维护的特定 APK 命名约定和目录结构。有没有办法做到这一点?

这是我当前的 gradle 构建结构(已简化并重命名以保护无辜者):

android {
    compileSdkVersion 25
    buildToolsVersion '25.0.3'
    defaultConfig {
        applicationId "com.mycompany.myapp"
        minSdkVersion 15
        targetSdkVersion 23
        versionCode 23
        versionName "23.23.23"
        compileOptions {
            sourceCompatibility JavaVersion.VERSION_1_7
            targetCompatibility JavaVersion.VERSION_1_7        }
        signingConfig signingConfigs.config
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt'
            signingConfig signingConfigs.config
        }
    }
    productFlavors.whenObjectAdded { flavor ->
        // Add the property 'myCustomProperty' to each product flavor and set the default value to 'customPropertyValue'
        flavor.ext.set('directoryPath', '')
        flavor.ext.set('apkName', '')
    }
    productFlavors {

        MyCompany {
            signingConfig signingConfigs.config
            directoryPath = mycompany
        }

        Copper {
            applicationId c
            signingConfig signingConfigs.config
            directoryPath = 'copper'
        }

        Steel {
            applicationId 'com.company2.steel'
            signingConfig signingConfigs.config
            directoryPath = 'steel'
        }

        Lead {
            applicationId 'com.company3.coal'
            signingConfig signingConfigs.config
            directoryPath = 'coal'
        }

    }


    applicationVariants.all { variant ->
        variant.outputs.each { output ->
            def path = "C:/AndroidBuilds/MyBuilds/" + variant.productFlavors[0].directoryPath + "/"
            logger.error("Path = " + path)
            def SEP = "-"
            def apkName = variant.productFlavors[0].apkName
            def flavor = variant.productFlavors[0].name
            if (apkName != '')
                flavor = apkName;
            def version = variant.versionCode
            def newApkName = path + version + SEP + flavor
            logger.error("newApkName = " + newApkName)
            output.outputFile = new File(newApkName + ".apk")
        }
    }
}

我知道现在有一个“风味维度”,我将默认设置(我删除它只是为了让代码更清晰一点)。运行此构建的结果应该是会生成 4 个不同的 APK,并将其放置在各自的目录结构中,并以版本号为前缀(例如“64-Iron.apk”)。

命名通过替换为“输出文件”起作用,但目录结构不起作用。在最新的 Gradle 下是否有新的方法可以做到这一点?

更新(已修复)

感谢所选解决方案提供的信息,为了完整起见,这里是最终的 gradle 配置(再次清理以保护无辜者):

android {
    compileSdkVersion 26
    defaultConfig {
        applicationId "com.mycompany.myapp"
        minSdkVersion 15
        targetSdkVersion 23
        versionCode 23
        versionName "23.23.23"
        compileOptions {
            sourceCompatibility JavaVersion.VERSION_1_7
            targetCompatibility JavaVersion.VERSION_1_7        }
        signingConfig signingConfigs.config
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt'
            signingConfig signingConfigs.config
        }
    }
    productFlavors.whenObjectAdded { flavor ->
        // Add the property 'myCustomProperty' to each product flavor and set the default value to 'customPropertyValue'
        flavor.ext.set('directoryPath', '')
        flavor.ext.set('apkName', '')
    }
    productFlavors {

        MyCompany {
            signingConfig signingConfigs.config
            directoryPath = mycompany
        }

        Copper {
            applicationId c
            signingConfig signingConfigs.config
            directoryPath = 'copper'
        }

        Steel {
            applicationId 'com.company2.steel'
            signingConfig signingConfigs.config
            directoryPath = 'steel'
        }

        Lead {
            applicationId 'com.company3.coal'
            signingConfig signingConfigs.config
            directoryPath = 'coal'
        }

    }

    applicationVariants.all { variant ->
        variant.outputs.all {
            def apkName = variant.productFlavors[0].apkName
            def flavor = variant.productFlavors[0].name
            if (apkName != '')
                flavor = apkName;
            //add here your logic to customize the name of the apk
            outputFileName = "${variant.versionCode}-${flavor}.apk"
        }
        variant.assemble.doLast { assemble ->
            //copy the apk in another directory, add here your
            //logic to customize the destination folder
            copy {
                from variant.outputs*.outputFile
                into "C:/AndroidBuilds/MyBuilds//${variant.productFlavors[0].directoryPath}"
            }
            //if you don't want to delete the file after copying it comment the line below
            delete variant.outputs*.outputFile
        }
    }
}

再次感谢 MatPag!

【问题讨论】:

    标签: android directory android-gradle-plugin


    【解决方案1】:

    更新:从 Gradle 3.3.0 开始,assemble 属性已弃用。这是执行此操作的新方法:

    applicationVariants.all { variant ->
        variant.outputs.all {
            //add here your logic to customize the name of the apk
            outputFileName = "${variant.name}-${variant.versionName}.apk"
        }
        variant.assembleProvider.configure { assemble ->
            assemble.doLast {
                //copy the apk in another directory, add here your
                //logic to customize the destination folder
                copy {
                    from variant.outputs*.outputFile
                    //for Windows
                    into "C:/my_apks/${variant.dirName}"
                }
                //if you don't want to delete the file after copying it comment the line below
                delete variant.outputs*.outputFile
            }
        }
    }
    

    在 macOS/Linux 中,您可以使用类似这样的东西作为目标 路径:

    into "${System.properties['user.home']}/my_apks/${variant.dirName}"
    

    旧答案(适用于 AGP 我用 Gradle 4.2.1 和 AGP 3.0.0 玩了一下,一个可能的解决方案就是这个

    applicationVariants.all { variant ->
        variant.outputs.all {
            //add here your logic to customize the name of the apk
            outputFileName = "${variant.name}-${variant.versionName}.apk"
        }
        variant.assemble.doLast { assemble ->
            //copy the apk in another directory, add here your
            //logic to customize the destination folder
            copy {
                from variant.outputs*.outputFile
                into "C:/my_apks/${variant.dirName}"
            }
            //if you don't want to delete the file after copying it comment the line below
            delete variant.outputs*.outputFile
        }
    }
    

    我认为根据您的需要自定义文件夹是一个很好的起点:)

    【讨论】:

    • 甜蜜。看起来很有希望......让我玩它,看看它是否有效。谢谢!
    • @StephenMcCormick 让我知道 ;)
    • 在修复了其他几个 Gradle 问题后,它的工作就像一个魅力!谢谢,干得好!
    • @Mark 我回家时会检查
    • @Mark 谢谢你的帮助。我已经更新了答案:)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-09-21
    • 2015-05-14
    • 2018-02-02
    • 2018-09-26
    相关资源
    最近更新 更多