kts之自定义输出apks目录的几种方法和bug解决

自定义文件名虽然很ok,但是这个目录因为渠道多了就显得乱七八糟的,我认为所有渠道应该度放到一个单独的文件夹,方便git忽略。
实现方法1:

applicationVariants.all {
        val artifactSuffix = buildString {
            productFlavors.getOrNull(0)?.name?.let { billingFlavorName ->
                if (billingFlavorName != Flavors.OSS) {
                    append(".$billingFlavorName")
                }
            }

            productFlavors.getOrNull(1)?.name?.let { infrastructureFlavorName ->
                if (infrastructureFlavorName != Flavors.PROD) {
                    append(".$infrastructureFlavorName")
                }
            }

            if (buildType.name != BuildTypes.RELEASE) {
                append(".${buildType.name}")
            }
        }

        val variantName = name
        val capitalizedVariantName = variantName.capitalized()
        val artifactName = "MullvadVPN-${versionName}${artifactSuffix}"

        tasks.register<Copy>("create${capitalizedVariantName}DistApk") {
            from(packageApplicationProvider)
            into("${rootDir.parent}/dist")
            include { it.name.endsWith(".apk") }
            rename { "$artifactName.apk" }
        }

        val createDistBundle =
            tasks.register<Copy>("create${capitalizedVariantName}DistBundle") {
                from("$buildDir/outputs/bundle/$variantName")
                into("${rootDir.parent}/dist")
                include { it.name.endsWith(".aab") }
                rename { "$artifactName.aab" }
            }

        createDistBundle.dependsOn("bundle$capitalizedVariantName")
    }

    project.tasks.preBuild.dependsOn("ensureJniDirectoryExist")
    project.tasks.preBuild.dependsOn("ensureValidVersionCode")
}

实现方法2:

fun copyWithAppFilename(dest: String, appName: String?) {
    delete("$dest/$coronaAppFileName.apk")
    delete("$dest/$coronaAppFileName.aab")
    var hasODR = false
    parsedBuildProperties.lookup<JsonArray<JsonObject>>("buildSettings.android.onDemandResources").firstOrNull()?.forEach {
        it["resource"].let { res ->
            hasODR = true
        }
    }

    copy {
        into(dest)
        val copyTask = this
        android.applicationVariants.matching {
            it.name.equals("release", true)
        }.all {
            if(!isExpansionFileRequired && !hasODR) {
                copyTask.from(packageApplicationProvider!!.get().outputDirectory) {
                    include("*.apk")
                    exclude("*unsigned*")
                }
            }
            copyTask.from("$buildDir/outputs/bundle/$name") {
                include("*.aab")
            }
        }
        rename {
            "$appName.${file(it).extension}"
        }
    }
}



tasks.create("buildCoronaApp") {
    description = "Used when Simulator invokes a build. It all project variables must be passed"
    dependsOn("assembleRelease")
    dependsOn("bundleRelease")
    dependsOn("createExpansionFile")

    coronaDstDir?.let {
        doLast {
            try {
                copyWithAppFilename(it, coronaAppFileName)
            } catch (ignore: Throwable) {
                try {
                    val defaultName = "App"
                    copyWithAppFilename(it, defaultName)
                    logger.error("WARNING: Used default filename '$defaultName' because original contains non-ASCII symbols.")
                } catch (ex: Throwable) {
                    logger.error("ERROR: Unable to finalize build. Make sure path to destination doesn't contain non-ASCII symbols")
                    throw ex
                }
            }
            delete("$it/$coronaExpansionFileName")
        }
    }
}

方法3

if (variant.buildType.name != "debug") {
            variant.packageApplicationProvider.get().outputDirectory = rootProject.file("apk/${variant.flavorName}")
        }

kt

if (this.buildType.name != "debug") {
                            this.packageApplicationProvider.configure{
                                this.outputDirectory.set( rootProject.file("apk/${floavorName}")) 
                            }
                        }

应该是需要忽略debug的,
我以前写的,不过没完全成功,
似乎不能直接改变目录会导致崩溃,而wan那个项目是忽略了debug

this.packageApplicationProvider.configure {
    //                            outputDirectory.set(File(project.rootDir.absolutePath + "/apks/${buildTypeName}/${floavorName}"))
                                doLast {
                                    val tasks = project.tasks.withType(AbstractArchiveTask::class.java)
                                    tasks.forEach { task ->
                                        if (task.name.contains(varinatNmae.capitalize())) {
                                            var outputFilePath =
                                                File(project.rootDir.absolutePath + "/apks/${buildTypeName}/${floavorName}")
                                            task.outputs.files.singleFile.copyTo(outputFilePath, true)
                                        } else {

                                        }
                                    }
                                }
                            }

2024-1-22 14:44:53 我想起来了,会导致output-metadata.json' which doesn't exist.
解决办法如下TestPine/app/build.gradle at 1377aba92e0d1f56bc7176febb4e47b6141579f7 · huaerxiela/TestPine (github.com)

很多人都选择了这种不靠谱的办法

image.png

然后我发现全是我们国人提交的代码
最后还有这种方法解决https://github.com/PhilGlass/android-cache-fix-gradle-plugin?tab=readme-ov-file

最后这个方法解决错误

tasks.configureEach { Task task ->
    if (!isModifyBuildOutputDirectory) return

    // 注意:如果是有多个 flavor,则为 merge“Flavor”DebugNativeLibs 的形式
    String taskName = task.name

    if (taskName.matches('^assemble.*[(Debug)|(Release)]$')) {

        def taskNameSplit = taskName.split('assemble')
        String variantName = taskNameSplit.size() > 0 ? taskNameSplit.last() : ''

        def variantNameSplit = variantName.split("(Debug)|(Release)")
        String flavorName = variantNameSplit.size() > 0 ? variantNameSplit.first() : ''

        String buildType = variantName - flavorName

        def apkListingFileRedirectTask = tasks.findByName("create${variantName}ApkListingFileRedirect")

        if (buildType.isBlank() || apkListingFileRedirectTask == null) {
            println "$task 非编译任务,无需修改打包输出目录"
            return
        }

        if (apkListingFileRedirectTask != null) {
            // 修改 apkListingFileRedirect 任务与 assembleVariantTask 任务的顺序
            apkListingFileRedirectTask.mustRunAfter(task)
        }

        task.doLast {
            println "------------------- ${taskName} end -------------------"

            // 修改生成 apk 的位置
            def outputDirectory = new File(rootProject.projectDir, "apk/")

            File listingFile = apkListingFileRedirectTask.property("listingFile").asFile.get()
            // apk 原始输出位置
            def buildApkOutputDirectory = listingFile.parentFile

            println "------------ 开始拷贝 ${outputDirectory} 到 ${buildApkOutputDirectory} 下  ----------"

            // 将打包生成的 apk 复制到 原有的构建目录
            copy {
                from outputDirectory
                into buildApkOutputDirectory
            }
        }
    }
}

BaseProject/commonGradle/apk_build.gradle at 580e913071577b2f9e56e5b5ea3cdb886f36c434 · Heart-Beats/BaseProject (github.com)

其它
参考源码UICore/_gradle/metadata.gradle at ad2806e09b057f3bdecd2c2fe6f52d06913df139 · angcyo/UICore (github.com)

mullvadvpn-app/android/app/build.gradle.kts at e0d794cd11d76e3d716b93cc84ec0bef9a7fe63d · mullvad/mullvadvpn-app (github.com)

corona/platform/android/app/build.gradle.kts at c2edbda89671314a0c6e06a07ea84125e1ba8018 · coronalabs/corona (github.com)wanandroid/app/build.gradle at 7b827f82fd0543bb3074f618a11f1076875bd2ae · lulululbj/wanandroid (github.com)

上面的方法都不靠谱,实际上自定义task是最靠谱的

image.png

我的解决办法

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值