Skip to content

多渠道打包

Android 多渠道打包用于为不同应用市场(华为、小米、应用宝等)生成定制化的 APK。

Product Flavors 配置

kotlin
android {
    // 声明维度
    flavorDimensions += listOf("market", "environment")
    
    productFlavors {
        // 市场渠道
        create("huawei") {
            dimension = "market"
            manifestPlaceholders["CHANNEL"] = "huawei"
        }
        create("xiaomi") {
            dimension = "market"
            manifestPlaceholders["CHANNEL"] = "xiaomi"
        }
        create("google") {
            dimension = "market"
            manifestPlaceholders["CHANNEL"] = "google"
        }
        
        // 环境
        create("dev") {
            dimension = "environment"
            applicationIdSuffix = ".dev"
            versionNameSuffix = "-dev"
            buildConfigField("String", "API_URL", "\"https://dev-api.example.com\"")
        }
        create("prod") {
            dimension = "environment"
            buildConfigField("String", "API_URL", "\"https://api.example.com\"")
        }
    }
    
    // 过滤不需要的变体组合
    variantFilter {
        // 排除 google + dev 组合
        if (flavors.map { it.name }.containsAll(listOf("google", "dev"))) {
            ignore = true
        }
    }
}

构建变体命令

bash
# 查看所有变体
./gradlew tasks | grep assemble

# 构建特定变体:huawei + prod + Release
./gradlew assembleHuaweiProdRelease

# 构建所有 prod Release 变体
./gradlew assembleProdRelease

# 构建所有变体(会很慢)
./gradlew assemble

渠道包批量打包脚本

kotlin
// build.gradle.kts
tasks.register("buildAllChannels") {
    group = "build"
    description = "构建所有渠道的 Release APK"
    
    val channels = listOf("huawei", "xiaomi", "google")
    dependsOn(channels.map { "assemble${it.capitalize()}ProdRelease" })
    
    doLast {
        channels.forEach { channel ->
            val apk = file("app/build/outputs/apk/${channel}Prod/release/")
            println("$channel APK: ${apk.listFiles()?.firstOrNull()?.name}")
        }
    }
}

渠道包 APK 重命名

kotlin
android {
    applicationVariants.all {
        val variant = this
        outputs.all {
            val output = this as com.android.build.gradle.internal.api.BaseVariantOutputImpl
            val channel = variant.flavorName
            val date = java.time.LocalDate.now().toString()
            output.outputFileName = "myapp-${channel}-${variant.versionName}-${date}.apk"
        }
    }
}

下一步