diff --git a/README.md b/README.md index f259300..4f34d21 100644 --- a/README.md +++ b/README.md @@ -34,7 +34,7 @@ signingConfigs { ``` groovy dependencies { classpath 'com.android.tools.build:gradle:7.0.3' - classpath 'com.tencent.vasdolly:plugin:3.0.4' + classpath 'com.tencent.vasdolly:plugin:3.0.5' } ``` ## 引用VasDolly Plugin @@ -46,7 +46,7 @@ apply plugin: 'com.tencent.vasdolly' 在主App工程的`build.gradle`中,添加读取渠道信息的helper类库依赖: ``` groovy dependencies { -    api 'com.tencent.vasdolly:helper:3.0.4' +    api 'com.tencent.vasdolly:helper:3.0.5' } ``` ## 配置渠道列表 @@ -75,12 +75,14 @@ channel{    channelFile = file("/Users/leon/Downloads/testChannel.txt") //多渠道包的输出目录,默认为new File(project.buildDir,"channel") outputDir = new File(project.buildDir,"xxx") - //多渠道包的命名规则,默认为:${appName}-${versionName}-${versionCode}-${flavorName}-${buildType}-${buildTime} + //多渠道包的命名规则,默认为:${appName}-${versionName}-${versionCode}-${aliasName}-${flavorName}-${buildType}-${buildTime} apkNameFormat ='${appName}-${versionName}-${versionCode}-${flavorName}-${buildType}' //快速模式:生成渠道包时不进行校验(速度可以提升10倍以上,默认为false) fastMode = false //buildTime的时间格式,默认格式:yyyyMMdd-HHmmss buildTimeDateFormat = 'yyyyMMdd-HH:mm:ss' + //渠道别名分割符 + channelSeparator = ' ' //低内存模式(仅针对V2签名,默认为false):只把签名块、中央目录和EOCD读取到内存,不把最大头的内容块读取到内存,在手机上合成APK时,可以使用该模式 lowMemory = false } @@ -92,6 +94,7 @@ channel{ * versionCode : 当前Variant的versionCode * buildType : 当前Variant的buildType,即debug or release * flavorName : 当前的渠道名称 +* aliasName: 当前的渠道别名 * appId : 当前Variant的applicationId * buildTime : 当前编译构建日期时间,时间格式可以自定义,默认格式:yyyyMMdd-HHmmss diff --git a/build.gradle b/build.gradle index 4fae3ea..da39770 100644 --- a/build.gradle +++ b/build.gradle @@ -7,7 +7,7 @@ ext { //VasDolly插件版本信息 GROUP = 'com.tencent.vasdolly' - VERSION = '3.0.4' + VERSION = '3.0.5' } buildscript { diff --git a/channel.txt b/channel.txt index 9227156..fe4dda2 100644 --- a/channel.txt +++ b/channel.txt @@ -1,10 +1,10 @@ -c1 -c2 -c3 -c4 -c5 -c6 -c7 -c8 -c9 -c10 \ No newline at end of file +c1 渠道1 +c2 渠道2 +c3 渠道3 +c4 渠道4 +c5 渠道5 +c6 渠道6 +c7 渠道7 +c8 渠道8 +c9 渠道9 +c10 渠道10 \ No newline at end of file diff --git a/plugin/src/main/kotlin/com/tencent/vasdolly/plugin/VasDollyPlugin.kt b/plugin/src/main/kotlin/com/tencent/vasdolly/plugin/VasDollyPlugin.kt index bd52414..2a3e80b 100644 --- a/plugin/src/main/kotlin/com/tencent/vasdolly/plugin/VasDollyPlugin.kt +++ b/plugin/src/main/kotlin/com/tencent/vasdolly/plugin/VasDollyPlugin.kt @@ -18,6 +18,7 @@ package com.tencent.vasdolly.plugin import com.android.build.api.variant.ApplicationVariant import com.tencent.vasdolly.plugin.extension.ChannelConfigExtension import com.tencent.vasdolly.plugin.extension.RebuildChannelConfigExtension +import com.tencent.vasdolly.plugin.model.Channel import com.tencent.vasdolly.plugin.task.ApkChannelPackageTask import com.tencent.vasdolly.plugin.task.RebuildApkChannelPackageTask import com.tencent.vasdolly.plugin.util.AndroidComponentsExtensionCompat @@ -44,7 +45,7 @@ class VasDollyPlugin : Plugin { private lateinit var rebuildConfigExt: RebuildChannelConfigExtension //渠道列表 - private var channelInfoList: List = listOf() + private var channelInfoList: List = listOf() override fun apply(project: Project) { this.project = project @@ -61,10 +62,6 @@ class VasDollyPlugin : Plugin { RebuildChannelConfigExtension::class.java, project ) - - //获取全局工程中配置的渠道列表(gradle.properties文件指定渠道属性) - channelInfoList = getChannelList() - //添加扩展渠道任务 createChannelTask() } @@ -79,6 +76,10 @@ class VasDollyPlugin : Plugin { if (variant is ApplicationVariant) { val variantName = variant.name.capitalize() println("find android build variant name:${variant.name}") + if(channelInfoList.isEmpty()){ + //获取全局工程中配置的渠道列表(gradle.properties文件指定渠道属性) + channelInfoList = getChannelList() + } project.tasks.register("channel$variantName", ApkChannelPackageTask::class.java) { it.variant = variant it.channelExtension = channelConfigExt @@ -103,13 +104,20 @@ class VasDollyPlugin : Plugin { * gradle rebuildChannel -Pchannels=yingyongbao,gamecenter * 这里通过属性channels指定的渠道列表拥有更高的优先级,且和原始的文件方式channel_file是互斥的 */ - private fun getChannelList(): List { - val channelList = mutableListOf() + private fun getChannelList(): List { + val channelList = mutableListOf() //检查是否配置channels属性(拥有更高的优先级,一般用于命令行测试用) if (project.hasProperty(PROPERTY_CHANNELS)) { val channels = project.properties[PROPERTY_CHANNELS] as String if (channels.isNotEmpty()) { - channelList = channels.split(",") + channelInfoList = channels.split(",").map { channel -> + if (channelConfigExt.channelSeparator.isNullOrEmpty()) { + Channel(channel, null) + } else { + val split = channel.split(channelConfigExt.channelSeparator!!) + Channel(split.first(), if (split.size > 1) split[1] else null) + } + } } if (channelList.isEmpty()) { throw InvalidUserDataException("Property(${PROPERTY_CHANNELS}) channel list is empty , please fix it") @@ -122,7 +130,15 @@ class VasDollyPlugin : Plugin { val channelFile = project.rootProject.file(channelFilePath) if (channelFile.exists() && channelFile.isFile) { channelFile.forEachLine { channel -> - channelList.add(channel) + if (channelConfigExt.channelSeparator.isNullOrEmpty()) { + val channelModel = Channel(channel, null) + channelList.add(channelModel) + } else { + val split = channel.split(channelConfigExt.channelSeparator!!) + val channelModel = + Channel(split.first(), if (split.size > 1) split[1] else null) + channelList.add(channelModel) + } } } } diff --git a/plugin/src/main/kotlin/com/tencent/vasdolly/plugin/extension/ChannelConfigExtension.kt b/plugin/src/main/kotlin/com/tencent/vasdolly/plugin/extension/ChannelConfigExtension.kt index e9e66b5..7a7f250 100644 --- a/plugin/src/main/kotlin/com/tencent/vasdolly/plugin/extension/ChannelConfigExtension.kt +++ b/plugin/src/main/kotlin/com/tencent/vasdolly/plugin/extension/ChannelConfigExtension.kt @@ -23,7 +23,7 @@ open class ChannelConfigExtension(project: Project) : ConfigExtension(project) { companion object { //默认文件名模板 const val DEFAULT_APK_NAME_FORMAT = - "${'$'}{appName}-${'$'}{versionName}-${'$'}{versionCode}-${'$'}{flavorName}-${'$'}{buildType}-${'$'}{buildTime}" + "${'$'}{appName}-${'$'}{versionName}-${'$'}{versionCode}-${'$'}{aliasName}-${'$'}{flavorName}-${'$'}{buildType}-${'$'}{buildTime}" //默认时间格式 const val DEFAULT_DATE_FORMAT = "yyyyMMdd-HHmmss" diff --git a/plugin/src/main/kotlin/com/tencent/vasdolly/plugin/extension/ConfigExtension.kt b/plugin/src/main/kotlin/com/tencent/vasdolly/plugin/extension/ConfigExtension.kt index f388d26..131da56 100644 --- a/plugin/src/main/kotlin/com/tencent/vasdolly/plugin/extension/ConfigExtension.kt +++ b/plugin/src/main/kotlin/com/tencent/vasdolly/plugin/extension/ConfigExtension.kt @@ -15,6 +15,7 @@ */ package com.tencent.vasdolly.plugin.extension +import com.tencent.vasdolly.plugin.model.Channel import org.gradle.api.Project import java.io.File @@ -32,18 +33,29 @@ open class ConfigExtension(var project: Project) { //渠道列表文件 var channelFile: File? = null + //渠道分割符号 + var channelSeparator: String? = null + //渠道包保持目录 var outputDir: File = File(project.buildDir,"channel") /** * 从扩展属性中获取channelFile配置的扩展渠道列表 */ - fun getExtensionChannelList(): List { - val channelList = mutableListOf() + fun getExtensionChannelList(): List { + val channelList = mutableListOf() if (channelFile != null && channelFile?.isFile!! && channelFile?.exists()!!) { channelFile?.forEachLine { channel -> if (channel.isNotEmpty()) { - channelList.add(channel) + if (channelSeparator.isNullOrEmpty()) { + val channelModel = Channel(channel, null) + channelList.add(channelModel) + } else { + val split = channel.split(channelSeparator!!) + val channelModel = + Channel(split.first(), if (split.size > 1) split[1] else null) + channelList.add(channelModel) + } } } println("get channels from `channelFile`,channels:$channelList") diff --git a/plugin/src/main/kotlin/com/tencent/vasdolly/plugin/model/Channel.kt b/plugin/src/main/kotlin/com/tencent/vasdolly/plugin/model/Channel.kt new file mode 100644 index 0000000..4777b4d --- /dev/null +++ b/plugin/src/main/kotlin/com/tencent/vasdolly/plugin/model/Channel.kt @@ -0,0 +1,12 @@ +package com.tencent.vasdolly.plugin.model + +/*** + * VasDolly插件 渠道信息 + * https://developer.android.com/studio/build/extend-agp + */ +data class Channel( + //渠道 + val channel: String, + //渠道别名 + val alias: String? +) \ No newline at end of file diff --git a/plugin/src/main/kotlin/com/tencent/vasdolly/plugin/task/ApkChannelPackageTask.kt b/plugin/src/main/kotlin/com/tencent/vasdolly/plugin/task/ApkChannelPackageTask.kt index 57d09cb..e6671aa 100644 --- a/plugin/src/main/kotlin/com/tencent/vasdolly/plugin/task/ApkChannelPackageTask.kt +++ b/plugin/src/main/kotlin/com/tencent/vasdolly/plugin/task/ApkChannelPackageTask.kt @@ -3,6 +3,7 @@ package com.tencent.vasdolly.plugin.task import com.android.build.api.artifact.SingleArtifact import com.android.build.api.variant.ApplicationVariant import com.tencent.vasdolly.plugin.extension.ChannelConfigExtension +import com.tencent.vasdolly.plugin.model.Channel import com.tencent.vasdolly.plugin.util.SimpleAGPVersion import org.gradle.api.GradleException import org.gradle.api.InvalidUserDataException @@ -114,7 +115,7 @@ open class ApkChannelPackageTask : ChannelPackageTask() { /*** * 获取渠道文件名 */ - override fun getChannelApkName(baseApkName: String, channel: String): String { + override fun getChannelApkName(baseApkName: String, channel: Channel): String { var timeFormat = ChannelConfigExtension.DEFAULT_DATE_FORMAT if (channelExtension?.buildTimeDateFormat!!.isNotEmpty()) { timeFormat = channelExtension?.buildTimeDateFormat!! @@ -124,7 +125,8 @@ open class ApkChannelPackageTask : ChannelPackageTask() { val keyValue: MutableMap = mutableMapOf() keyValue["appName"] = project.name - keyValue["flavorName"] = channel + keyValue["flavorName"] = channel.channel + keyValue["aliasName"] = channel.alias ?: channel.channel keyValue["buildType"] = variant?.buildType ?: "" keyValue["versionName"] = outInfo?.versionName?.get() ?: "" keyValue["versionCode"] = outInfo?.versionCode?.get().toString() @@ -145,7 +147,7 @@ open class ApkChannelPackageTask : ChannelPackageTask() { /*** * 获取渠道列表 */ - override fun getExtensionChannelList(): List { + override fun getExtensionChannelList(): List { return channelExtension?.getExtensionChannelList() ?: listOf() } } \ No newline at end of file diff --git a/plugin/src/main/kotlin/com/tencent/vasdolly/plugin/task/ChannelPackageTask.kt b/plugin/src/main/kotlin/com/tencent/vasdolly/plugin/task/ChannelPackageTask.kt index 8c32996..42fe12e 100644 --- a/plugin/src/main/kotlin/com/tencent/vasdolly/plugin/task/ChannelPackageTask.kt +++ b/plugin/src/main/kotlin/com/tencent/vasdolly/plugin/task/ChannelPackageTask.kt @@ -1,5 +1,6 @@ package com.tencent.vasdolly.plugin.task +import com.tencent.vasdolly.plugin.model.Channel import com.tencent.vasdolly.reader.ChannelReader import com.tencent.vasdolly.verify.VerifyApk import com.tencent.vasdolly.writer.ChannelWriter @@ -15,7 +16,7 @@ abstract class ChannelPackageTask : DefaultTask() { var mergeExtChannelList: Boolean = true @Input - var channelList: MutableList = mutableListOf() + var channelList: MutableList = mutableListOf() init { group = "com.tencent.vasdolly" @@ -50,10 +51,10 @@ abstract class ChannelPackageTask : DefaultTask() { if (apkSectionInfo.lowMemory) { baseApk.copyTo(destFile) } - ChannelWriter.addChannelByV2(apkSectionInfo, destFile, channel) + ChannelWriter.addChannelByV2(apkSectionInfo, destFile, channel.channel) if (!isFastMode) { //1. verify channel info - if (ChannelReader.verifyChannelByV2(destFile, channel)) { + if (ChannelReader.verifyChannelByV2(destFile, channel.channel)) { println("generateV2ChannelApk, $destFile add channel success") } else { throw GradleException("generateV2ChannelApk, $destFile add channel failure") @@ -99,10 +100,10 @@ abstract class ChannelPackageTask : DefaultTask() { println("generateV1ChannelApk,channel=$channel,apkChannelName=$apkChannelName") val destFile = File(outputDir, apkChannelName) baseApk.copyTo(destFile) - ChannelWriter.addChannelByV1(destFile, channel) + ChannelWriter.addChannelByV1(destFile, channel.channel) if (isFastMode) { //1. verify channel info - if (ChannelReader.verifyChannelByV1(destFile, channel)) { + if (ChannelReader.verifyChannelByV1(destFile, channel.channel)) { println("generateV1ChannelApk,apk $destFile add channel success") } else { throw GradleException("generateV1ChannelApk,apk $destFile add channel failure") @@ -118,8 +119,8 @@ abstract class ChannelPackageTask : DefaultTask() { println("------$project.name:$name generate v1 channel apk , end------") } - abstract fun getChannelApkName(baseApkName: String, channel: String): String + abstract fun getChannelApkName(baseApkName: String, channel: Channel): String @Internal - abstract fun getExtensionChannelList(): List + abstract fun getExtensionChannelList(): List } \ No newline at end of file diff --git a/plugin/src/main/kotlin/com/tencent/vasdolly/plugin/task/RebuildApkChannelPackageTask.kt b/plugin/src/main/kotlin/com/tencent/vasdolly/plugin/task/RebuildApkChannelPackageTask.kt index 2807d7e..d6c8484 100644 --- a/plugin/src/main/kotlin/com/tencent/vasdolly/plugin/task/RebuildApkChannelPackageTask.kt +++ b/plugin/src/main/kotlin/com/tencent/vasdolly/plugin/task/RebuildApkChannelPackageTask.kt @@ -1,6 +1,7 @@ package com.tencent.vasdolly.plugin.task import com.tencent.vasdolly.plugin.extension.RebuildChannelConfigExtension +import com.tencent.vasdolly.plugin.model.Channel import com.tencent.vasdolly.reader.ChannelReader import org.gradle.api.GradleException import org.gradle.api.InvalidUserDataException @@ -77,15 +78,19 @@ open class RebuildApkChannelPackageTask : ChannelPackageTask() { /** * 获取Apk文件名 */ - override fun getChannelApkName(baseApkName: String, channel: String): String { + override fun getChannelApkName(baseApkName: String, channel: Channel): String { return if (baseApkName.contains("base")) { - baseApkName.replace("base", channel) + baseApkName.replace("base", channel.channel) } else { - "$channel-$baseApkName"; + if(channel.alias.isNullOrEmpty()){ + "${channel.channel}-$baseApkName" + }else{ + "${channel.alias}-${channel.channel}-$baseApkName" + } } } - override fun getExtensionChannelList(): List { + override fun getExtensionChannelList(): List { return rebuildExt?.getExtensionChannelList() ?: listOf() } } \ No newline at end of file