Android Gradle8.0以上多渠道写法以及针对不同渠道导入包的方式,填坑!

目录

多渠道的写法

针对多渠道引用不同的包

There was a failure while populating the build operation queue: Could not stat file E:\xxxx\xxxx\xxxx\app\src\UAT\libsUAT\xxx-provider(?)-xx.aar


最近升级了Gradle8.3之后,从Groovy 迁移到 Kotlin,很多写法都有发生改变。

其他的不细说了,针对这篇文章的主题,多渠道写法 以及 不同渠道如何导入不同的包 来讲。

多渠道的写法

日常单一渠道的话,一般会用这种方式去区分环境。在8.0以下的写法是:

productFlavors {
        DEV {
            dimension 'XXXXX'
            applicationIdSuffix '.dev'
            buildConfigField "String", "DOMAIN", '"https://XXXXX/"'
            buildConfigField "String", "XXXX_RETURN_URL", '"scheme://host"'
            buildConfigField "String", "XXXX_RETURN_URL", '"scheme://host"'
            buildConfigField "String", "XXXX_RETURN_URL", '"scheme://host"'
            buildConfigField "Long", "BUILD_DATE", "${buildDate}L"
            manifestPlaceholders = [
                    app_name          : "(DEV)XXXX",
                    DEEP_LINK_HOST    : "DOMAINXXXXX",
            ]
        }
        
        UAT {}

        PROD {}
}

但在8.0以上,写法要改成

productFlavors {
        create("DEV").apply {
            this.dimension = "xxxxx"
            this.applicationIdSuffix = ".dev"
            this.buildConfigField("String", "DOMAIN", "\"https://XXXXXX/\"")
            this.buildConfigField("String", "XXXX_RETURN_URL", "\"scheme://host\"")
            this.buildConfigField("String", "XXXX_RETURN_URL", "\"scheme://host\"")
            this.buildConfigField("String", "XXXX_RETURN_URL", "\"scheme://host\"")
            this.buildConfigField("Long", "BUILD_DATE", "${buildDate}L")
            this.manifestPlaceholders.apply {
                this["app_name"] to "(DEV)XXXXX"
                this["DEEP_LINK_HOST"] to "DOMAINXXXX"
            }
        }
        
        create("UAT").apply {}

        create("PROD").apply {}
}

针对多渠道引用不同的包

这个可能不是每个人都需要,我是遇到是这个问题。

背景:台湾的支付平台SDK,UAT跟PROD给了两个SDK,同时导入会引发重复包的错误,不然就需要在开发阶段,放置UAT的SDK,等上线的时候记得替换PROD的SDK,这样存在一定的风险,可能会忘记替换等等原因。我希望做成当切换渠道(环境)的时候,自动切换到不同的SDK。

正常引用SDK,我们是使用下面这两种方式

dependencies {
    implementation(files("XXXX"))
    implementation(fileTree(mapOf("dir" to "../XXXX/libs", "include" to listOf("*.jar","*.aar"))))
}

我没在Gradle8.0以下针对不同渠道引用不同的SDK,没办法给出8.0以下的写法,我将8.0以上的写法直接贴出来

// 对于特定的flavor,使用特定的dependencies
val libsProdPath = "src/PROD/libsPROD/XXXXX.aar"
val libsUATPath = "src/UAT/libsUAT/XXXXX.aar"

configurations {
    "PRODImplementation" {
        extendsFrom(configurations.implementation.get())
    }
    "UATImplementation" {
        extendsFrom(configurations.implementation.get())
    }
}

dependencies {
    // implementation(fileTree(mapOf("dir" to "../XXXXX/libs", "include" to listOf("*.jar","*.aar"))))
    "PRODImplementation"(files(libsProdPath))
    "UATImplementation"(files(libsUATPath))
}

这样在build的时候,就能根据不同的渠道(环境)去拿到对应的路径下的SDK文件了。

我需要加载多个SDK,所以改成了

// 对于特定的flavor,使用特定的dependencies
val libsProdPath = listOf(
    "src/PROD/libsPROD/XXXXX.aar",
    "src/PROD/libsPROD/XXXXX.aar",
    "src/PROD/libsPROD/XXXXX.aar"
)
val libsUATPath = listOf(
    "src/UAT/libsUAT/XXXXX.aar",
    "src/UAT/libsUAT/XXXXX.aar",
    "src/UAT/libsUAT/XXXXX.aar"
)
configurations {
    "PRODImplementation" {
        extendsFrom(configurations.implementation.get())
    }
    "UATImplementation" {
        extendsFrom(configurations.implementation.get())
    }
}

dependencies {
    // implementation(fileTree(mapOf("dir" to "../XXXXX/libs", "include" to listOf("*.jar","*.aar"))))
    "PRODImplementation"(files(libsProdPath))
    "UATImplementation"(files(libsUATPath))
}

后面又觉得把版本号写固定在路径下并不方便,于是把版本号抽出来,由于我其他的libs的版本号都写在libs.versions.toml下统一管理,于是也很自然而然的去这个文件下添加了

[versions]
xxxxxVersion = "x.y.z"

但当我回来build.gradle.kts修改为如下之后

// 对于特定的flavor,使用特定的dependencies
val libsProdPath = listOf(
    "src/PROD/libsPROD/XXX-${libs.versions.xxxxxVersion}-XX.aar",
    "src/PROD/libsPROD/XXX-${libs.versions.xxxxxVersion}-XX.aar",
    "src/PROD/libsPROD/XXX-${libs.versions.xxxxxVersion}-XX.aar"
)
val libsUATPath = listOf(
    "src/UAT/libsUAT/XXX-${libs.versions.xxxxxVersion}-XX.aar",
    "src/UAT/libsUAT/XXX-${libs.versions.xxxxxVersion}-XX.aar",
    "src/UAT/libsUAT/XXX-${libs.versions.xxxxxVersion}-XX.aar"
)
configurations {
    "PRODImplementation" {
        extendsFrom(configurations.implementation.get())
    }
    "UATImplementation" {
        extendsFrom(configurations.implementation.get())
    }
}

dependencies {
    // implementation(fileTree(mapOf("dir" to "../XXXXX/libs", "include" to listOf("*.jar","*.aar"))))
    "PRODImplementation"(files(libsProdPath))
    "UATImplementation"(files(libsUATPath))
}

出现了问题,Sync的时候提示错误:

There was a failure while populating the build operation queue: Could not stat file E:\xxxx\xxxx\xxxx\app\src\UAT\libsUAT\xxx-provider(?)-xx.aar

找不到文件?为什么找不到,因为版本号没有被正确的加载,变成了provider(?)。

猜测是因为Gradle在执行阶段的时候引用了没有被正确解析的变量,最后通过provider来延迟加载版本号,以确保在配置阶段能够正确加载到版本号

于是,最终代码如下:

val xxxxxVersionProvider: Provider = providers.provider { libs.versions.xxxxxVersion.get() }

// 对于特定的flavor,使用特定的dependencies
val libsProdPath = listOf(
    "src/PROD/libsPROD/XXX-${xxxxxVersionProvider.get()}-XX.aar",
    "src/PROD/libsPROD/XXX-${xxxxxVersionProvider.get()}-XX.aar",
    "src/PROD/libsPROD/XXX-${xxxxxVersionProvider.get()}-XX.aar"
)
val libsUATPath = listOf(
    "src/UAT/libsUAT/XXX-${xxxxxVersionProvider.get()}-XX.aar",
    "src/UAT/libsUAT/XXX-${xxxxxVersionProvider.get()}-XX.aar",
    "src/UAT/libsUAT/XXX-${xxxxxVersionProvider.get()}-XX.aar"
)
configurations {
    "PRODImplementation" {
        extendsFrom(configurations.implementation.get())
    }
    "UATImplementation" {
        extendsFrom(configurations.implementation.get())
    }
}

dependencies {
    // implementation(fileTree(mapOf("dir" to "../XXXXX/libs", "include" to listOf("*.jar","*.aar"))))
    "PRODImplementation"(files(libsProdPath))
    "UATImplementation"(files(libsUATPath))
}

这样就能完美根据Build Variants中选择的Active Build Variant,build.gradle.kts自动去找到相对应的SDK了。

代码中所有实际项目相关的内容,都用【xxxxx】隐去,相应的路径、文件名,大家便根据各自实际情况修改了,有问题可以留言。

本文终。

你可能感兴趣的:(Android例子,android,Gradle8.0+,dependencies,implementation,多渠道)