问小白 wenxiaobai
资讯
历史
科技
环境与自然
成长
游戏
财经
文学与艺术
美食
健康
家居
文化
情感
汽车
三农
军事
旅行
运动
教育
生活
星座命理

Android Gradle开发:脚本实现自动打包后复制APK文件并备份

创作时间:
作者:
@小白创作中心

Android Gradle开发:脚本实现自动打包后复制APK文件并备份

引用
CSDN
1.
https://blog.csdn.net/jdsjlzx/article/details/139077989

在Android应用开发过程中,自动打包并备份APK文件是一个常见的需求。本文将介绍如何通过Gradle脚本实现这一功能,包括三种不同的实现方法,帮助开发者自动化处理APK文件的复制和命名。

方法一:在build.gradle中直接配置

build.gradle (:app)文件中添加以下脚本,可以在每次打包完成后自动将APK文件复制到指定目录,并重命名:

android {
    ...
    // 打包完成复制一份到apk文件夹内
    this.project.afterEvaluate { project ->
        project.tasks.each { task ->
            if (task.toString().contains("assemble")) {
                task.doLast {
                    android.applicationVariants.all { variant ->
                        def simpleName = "app-${variant.buildType.name}.apk"
                        // 默认生成apk的文件夹
                        def workFolder = "${project.getProjectDir().path}/build/outputs/apk/${variant.buildType.name}"
                        // 定义目标文件夹
                        def destFolder = new File("${project.getProjectDir().path}/apk/${variant.buildType.name}")
                        try {
                            if (!destFolder.exists()) {
                                destFolder.mkdir()
                            }
                            copy {
                                from "${workFolder}/${simpleName}"
                                into "${destFolder}/"
                                rename {
                                    "property_v${versionName}_${versionCode}_${variant.buildType.name}.apk"
                                }
                            }
                        } catch (Exception e) {
                            print e
                        }
                    }
                }
            }
        }
    }
}

这样在每次assembleXXXX任务的时候,或者Build的时候,都会在打包完成后复制一份到/app/apk/下面。

方法二:使用Gradle脚本实现多渠道打包

方法二之一

android.applicationVariants.all { variant ->
    // 打包完成后输出路径
    def name = "app" +
            "_" + variant.flavorName +
            "_" + variant.buildType.name +
            "_" + variant.versionName +
            "_" + new Date().format('yyyy-MM-dd') + ".apk"

    def path = "../../../../../apk/" //相当于路径 app/apk/
    variant.outputs.each { output ->
        def outputFile = output.outputFile
        if (outputFile != null && outputFile.name.endsWith('.apk')) {
            //指定路径输出
            output.outputFileName = new File(path, name)
        }
    }
}

方法二之二

android.applicationVariants.all { variant ->
    variant.outputs.forEach {
        it.outputFileName = "${variant.productFlavors[0].name}_v${defaultConfig.versionName}_${new Date().format('yyyy-MM-dd')}.apk"
    }

    //  打包完成后复制到的目录
    def outputFileDir = "${project.projectDir.absolutePath}/apk/"

    // 打包完成后做的一些事,复制apk到指定文件夹
    variant.assemble.doLast {
        File out = new File(outputFileDir)
        copy {
            variant.outputs.forEach { file ->
                //复制到指定文件夹
                //copy {
                //      from file.outputFile
                //      into out
                //}
                  //移动到指定文件夹
                  ant.move file: file.outputFile,
                    todir: "${project.rootDir}/apk"
            }
        }
    }
}

方法三:使用独立的Gradle脚本文件

配置位置

app模块的build.gradle文件中添加以下依赖:

apply from: "../copy_apk.gradle"

copy_apk.gradle 文件内容

project.archivesBaseName = "XXXApp"
static def releaseTime() {
    return new Date().format("HHmmss")//yyyyMMdd_HHmmss
}
android.applicationVariants.all { variant ->
    variant.outputs.all {
        if (outputFileName.endsWith('.apk')) {
            //这里使用之前定义apk文件名称
//            outputFileName = "${project.archivesBaseName}_v${variant.productFlavors[0].versionName}_${variant.productFlavors[0].versionCode}_${variant.productFlavors[0].name}_${releaseTime()}_${variant.buildType.name}.apk"
            outputFileName = "${project.archivesBaseName}_${versionCode}_v${versionName}_${releaseTime()}_${name}.apk"
        }
    }
    //复制到根目录下的output文件夹
    File desFilePath = new File("${rootDir}/output")
    //删除output目录
    delete desFilePath
    //API 'variant.getAssemble()' is obsolete and has been replaced with 'variant.getAssembleProvider()'.
    //It will be removed in version 7.0 of the Android Gradle plugin.
    //编译完成后将apk复制到指定目录
//    variant.assemble.doLast {
//        variant.outputs.all {
//            try {
//                //判断文件夹是否存在
//                if (!desFilePath.exists()) {
//                    desFilePath.mkdir()
//                }
//                //将编译好的apk 复制到output目录
//                copy {
//                    from outputFile
//                    into desFilePath
//                    include '**/*.apk'
//                }
//            } catch (Exception e) {
//                e.printStackTrace()
//            }
//        }
//    }
    //used variant.getAssembleProvider().
    //(variant.assembleProvider.configure|variant.assembleProvider.get.doLast)
    //https://stackoverflow.com/questions/54193510/while-android-studio-updated-to-v3-3-getting-api-variant-getassemble-is-obso
    variant.assembleProvider.configure {
        it.doLast {
            variant.outputs.all {
                try {
                    //判断文件夹是否存在
                    if (!desFilePath.exists()) {
                        desFilePath.mkdir()
                    }
                    //将编译好的apk 复制到output目录
                    copy {
                        from outputFile
                        into desFilePath
                        include '**/*.apk'
                    }
                } catch (Exception e) {
                    e.printStackTrace()
                }
            }
        }
    }
}

© 2023 北京元石科技有限公司 ◎ 京公网安备 11010802042949号