Gradle 打包 APK 重命名

本文首发于我的个人博客,此处只为简单转载

背景

最近脑子一热,又想捡回来 MyLuaApp,于是开了这个新坑 AndroCode

准备在里面实现加载插件,也就是插件化的效果。

在开发的时候,希望能测试从 apk 里加载插件的效果,但是又不想每次都手动复制粘贴插件的 apk 包到项目的 assets 目录下。

于是就想到了用 Gradle,在打插件包的时候把插件包的 apk 自动复制到主项目的 assets 目录下。

实现

整体代码很简单,但是我自己摸索了几个小时之后,才弄出来。。

1. 遍历 applicationVariants,重命名 APK

kotlin 复制代码
android {
    //...
    applicationVariants.all {
        logger.lifecycle("Configure application variant $name")

        val appProject = project(":app")

        // 自定义后面复制apk 的输出路径
        val outputFileDir =
            "${appProject.projectDir}/src/main/assets/plugins"

        // 自定义文件名        
        val path = project.name + "-" +buildType.name + "-" +
                versionName + ".apk"

        outputs
            // 如果不去拿 internal 包里的类,这个 output 里面就没有 outputFileName 字段
            // default type don't have outputFileName field
            .map { it as com.android.build.gradle.internal.api.ApkVariantOutputImpl }
            .all { output ->
                output.outputFileName = path
                false
            }

    }
}

注意在遍历 outputs 之前需要把里面的输出转成内部类,否则会找不到 outputFileName 字段。

2. 复制 APK 到 assets 目录

kotlin 复制代码
android {
    //...
    applicationVariants.all {
        // ...

   
        // 获取 app 模块的 preBuild 任务
        appProject.getTasksByName("pre${name.capitalized()}Build", true).forEach {
            it.apply {
                // 要求在打包 app 模块之前,先打包插件
                dependsOn(this@all.assembleProvider.get())
            }
        }

        // 配置当前变体的 assemble 任务,在完成后复制 APK 到 assets 目录下
        // 因为上面的依赖关系,就可以保证在复制后才开始打包 app 模块,保证 app 模块里打出来的包有我们这个插件 apk
        assembleProvider.configure {       
            doLast {
                copy {
                    this@all.outputs.forEach { file ->
                        copy {
                            from(file.outputFile)
                            into(outputFileDir)
                        }
                    }
                }
            }
        }

    }
}

上面的代码中我们在 app 模块的 preBuild 任务中配置要求依赖了 当前变体的 assemble 任务,这样在复制 APK 到 assets 目录下的时候,就保证了插件包的 apk 已经打好了。

然后在当前变体的 assemble 任务中,在完成后复制 APK 到 assets 目录下。

其实很简单的几十行代码,但是我查询了很多资料才完成了这个需求。。。下面贴上完整源代码:

kotlin 复制代码
android {
     applicationVariants.all {
        logger.lifecycle("Configure application variant $name")

        val appProject = project(":app")

        val outputFileDir =
            "${appProject.projectDir}/src/main/assets/plugins"

        val path = project.name + "-" +buildType.name + "-" +
                versionName + ".apk"

        outputs
            // default type don't have outputFileName field
            .map { it as com.android.build.gradle.internal.api.ApkVariantOutputImpl }
            .all { output ->
                output.outputFileName = path
                false
            }

        appProject.getTasksByName("pre${name.capitalized()}Build", true).forEach {
            it.apply {
                dependsOn(this@all.assembleProvider.get())
            }
        }

        assembleProvider.configure {
           
            doLast {
                copy {
                    this@all.outputs.forEach { file ->
                        copy {
                            from(file.outputFile)
                            into(outputFileDir)
                        }
                    }
                }
            }
        }
    }
}

总结

这是一个简单的需求,但是我花了几小时,查询了不少文档才实现的。。。

如果有更好的实现方式,欢迎留言。

参考

Android gradle plugin 8.1.0 change apk name

gradle在prebuild之前执行task

Android gradle配置生成的apk名称和存放位置

AndroidStudio2021/3版 gradle7.0环境 自定义输出apk路径

相关推荐
工程师老罗7 小时前
如何在Android工程中配置NDK版本
android
Libraeking10 小时前
破壁行动:在旧项目中丝滑嵌入 Compose(混合开发实战)
android·经验分享·android jetpack
市场部需要一个软件开发岗位11 小时前
JAVA开发常见安全问题:Cookie 中明文存储用户名、密码
android·java·安全
JMchen12312 小时前
Android后台服务与网络保活:WorkManager的实战应用
android·java·网络·kotlin·php·android-studio
crmscs13 小时前
剪映永久解锁版/电脑版永久会员VIP/安卓SVIP手机永久版下载
android·智能手机·电脑
localbob13 小时前
杀戮尖塔 v6 MOD整合版(Slay the Spire)安卓+PC端免安装中文版分享 卡牌肉鸽神作!杀戮尖塔中文版,电脑和手机都能玩!杀戮尖塔.exe 杀戮尖塔.apk
android·杀戮尖塔apk·杀戮尖塔exe·游戏分享
机建狂魔13 小时前
手机秒变电影机:Blackmagic Camera + LUT滤镜包的专业级视频解决方案
android·拍照·摄影·lut滤镜·拍摄·摄像·录像
hudawei99613 小时前
flutter和Android动画的对比
android·flutter·动画
lxysbly15 小时前
md模拟器安卓版带金手指2026
android
儿歌八万首16 小时前
硬核春节:用 Compose 打造“赛博鞭炮”
android·kotlin·compose·春节