安卓工程-多渠道打包与签名文件配置
1.修改buildTypes,新增打包类型
plugins {
id 'com.android.application'
id 'org.jetbrains.kotlin.android'
}
android {
compileSdk 31
defaultConfig {
applicationId "com.example.android_kotlin"
minSdk 19
targetSdk 31
versionCode 1
versionName "1.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
buildTypes {
// release {
// minifyEnabled false
// proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
// }
getByName("release") {
minifyEnabled = true
proguardFiles(getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro")
}
getByName("debug") {
applicationIdSuffix = ".debug"
debuggable = true
}
create("staging") {
initWith(getByName("debug"))
manifestPlaceholders["hostName"] = "internal.example.com"
applicationIdSuffix = ".debugStaging"
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
kotlinOptions {
jvmTarget = '1.8'
}
}
dependencies {
implementation 'androidx.core:core-ktx:1.7.0'
implementation 'androidx.appcompat:appcompat:1.3.0'
implementation 'com.google.android.material:material:1.4.0'
implementation 'androidx.constraintlayout:constraintlayout:2.0.4'
testImplementation 'junit:junit:4.13.2'
androidTestImplementation 'androidx.test.ext:junit:1.1.3'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
}
修改后,可以打出三程不同类型的包
release:包名为 defaultConfig里配置的applicationId,如 applicationId "com.example.android_kotlin"
debug:包名为release版本的applicationId加上.debug
staging:包名为release版本的applicationId加上.debugStaging或者.releaseStaging
包名不同,所以可以三个版本安装到同一个设备上而不会相互覆盖
不同的打包类型,生成的BuildConfig内容也不同
public final class BuildConfig {
public static final boolean DEBUG = Boolean.parseBoolean("true");
public static final String APPLICATION_ID = "com.example.android_kotlin.debug";
public static final String BUILD_TYPE = "debug";
public static final int VERSION_CODE = 1;
public static final String VERSION_NAME = "1.0";
}
2.添加productFlavors
// Specifies one flavor dimension.
flavorDimensions += "version"
productFlavors {
create("demo") {
// Assigns this product flavor to the "version" flavor dimension.
// If you are using only one dimension, this property is optional,
// and the plugin automatically assigns all the module's flavors to
// that dimension.
dimension = "version"
applicationIdSuffix = ".demo"
versionNameSuffix = "-demo"
}
create("full") {
dimension = "version"
applicationIdSuffix = ".full"
versionNameSuffix = "-full"
}
}
修改后可以打出来的包有以下几种选择
demoDebug demoRelease demoStaging fullDebug fullRelease fullStaging
包名不同,并且版本号名称也不同
生成的 demo debug BuildConfig文件内容 如下
public final class BuildConfig {
public static final boolean DEBUG = Boolean.parseBoolean("true");
public static final String APPLICATION_ID = "com.example.android_kotlin.demo.debug";
public static final String BUILD_TYPE = "debug";
public static final String FLAVOR = "demo";
public static final int VERSION_CODE = 1;
public static final String VERSION_NAME = "1.0-demo";
}
配置签名
signingConfigs {
create("signing-release") {
storeFile = file("my_debug_key.jks")
storePassword = "my_debug_key"
keyAlias = "my_debug_key"
keyPassword = "my_debug_key"
}
create("signing-debug") {
storeFile = file("my_debug_key.jks")
storePassword = "my_debug_key"
keyAlias = "my_debug_key"
keyPassword = "my_debug_key"
}
}
buildTypes {
// release {
// minifyEnabled false
// proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
// }
getByName("release") {
minifyEnabled = true
proguardFiles(getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro")
signingConfig = signingConfigs.getByName("signing-release")
}
getByName("debug") {
applicationIdSuffix = ".debug"
debuggable = true
signingConfig = signingConfigs.getByName("signing-debug")
}
create("staging") {
initWith(getByName("debug"))
manifestPlaceholders["hostName"] = "internal.example.com"
applicationIdSuffix = ".debugStaging"
signingConfig = signingConfigs.getByName("signing-release")
}
}
3.实现自定义修改打包后的apk的名称,并复制到指定文件夹
在项目根目录下新建buildReleaseApiFile.gradle文件
static def getOutputFileName(variant) {
def productName = variant.productFlavors[0].name
def versionCode = variant.versionCode
def versionName = variant.versionName
def buildType = variant.buildType.name.contains("release") ? "发布版" : "调试版"
if(variant.buildType.name.contains("debug")) {
return "${versionCode}_${versionName}.apk"
}
def _date = new Date().format("yyyy-MM-dd-HH-mm")
def nameMap = [ huawei: "华为应用市场", xiaomi: "小米应用市场", other : "其他应用市场", ]
return "${nameMap[productName]}_${buildType}__版本名称_${versionName}__版本号_${versionCode}__打包时间_${_date}.apk"
}
android.applicationVariants.all { variant ->
variant.outputs.all {
//指定apk文件打包生成的名称
outputFileName = getOutputFileName(variant)
}
}
def getApkFileDir() {
return "${rootProject.projectDir.absolutePath}${File.separator}" +
"app${File.separator}" +
"build${File.separator}" +
"outputs${File.separator}" +
"apk${File.separator}"
}
//打包完成后,把生成的文件复制到指定文件夹
def copyReleaseFile() {
println("copyReleaseFile run")
def path = getApkFileDir()
file(path)?.listFiles()?.each {
def _file = file("${it.absolutePath}${File.separator}release")
_file.listFiles()?.each { apkFile ->
if (apkFile.absolutePath.endsWith(".apk") && apkFile.exists()) {
println(apkFile.absolutePath)
def _from = apkFile.absolutePath
def _into = "${rootProject.projectDir.absolutePath}${File.separator}" +
"outputs${File.separator}${new Date().format("yyyy-MM-dd")}"
if (!file(_into).exists()) {
file(_into)?.mkdirs()
}
println("_from:$_from")
println("_into:$_into")
copy {
from apkFile.absolutePath
into _into
}
println("delete:${apkFile.absolutePath}")
apkFile.delete()
}
}
}
}
//在某项task完成后执行相应方法。经测试有点小问题
project.tasks.whenTaskAdded { Task theTask ->
println("whenTaskAdded:${theTask.name}")
// if (theTask.name == 'assembleRelease') {
// if (theTask.name.startsWith("assemble")) {
// theTask.doLast {
// // 编译完apk之后再执行自定义task
// copyReleaseFile()
// }
// }
}
//在命令行里执行 gradlew buildReleaseApkFile就会自动执行打包和复制命令
tasks.create("buildReleaseApkFile") {
doFirst {
copyReleaseFile()
}
doLast {
delete file(getApkFileDir())
}
}.dependsOn(":app:assembleRelease")
引入到app下的build.gradle里 apply from: "../buildReleaseApkFile.gradle"
plugins {
id 'com.android.application'
id 'org.jetbrains.kotlin.android'
}
android {
compileSdk 31
defaultConfig {
applicationId "com.example.android_kotlin"
minSdk 19
targetSdk 31
versionCode 1
versionName "1.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
//指定打包签名信息
signingConfigs {
create("signing-release") {
storeFile = file("my_debug_key.jks")
storePassword = "my_debug_key"
keyAlias = "my_debug_key"
keyPassword = "my_debug_key"
}
create("signing-debug") {
storeFile = file("my_debug_key.jks")
storePassword = "my_debug_key"
keyAlias = "my_debug_key"
keyPassword = "my_debug_key"
}
}
buildTypes {
getByName("release") {
minifyEnabled = true
// debuggable = true
proguardFiles(getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro")
signingConfig = signingConfigs.getByName("signing-release")
}
getByName("debug") {
//配置debug安装包的包名后缀
applicationIdSuffix = ".debug"
debuggable = true
signingConfig = signingConfigs.getByName("signing-debug")
}
create("staging") {
initWith(getByName("debug"))
manifestPlaceholders["hostName"] = "internal.example.com"
//配置安装包的包名后缀
applicationIdSuffix = ".debugStaging"
signingConfig = signingConfigs.getByName("signing-release")
}
}
flavorDimensions += "version"
productFlavors {
create("huawei") {
//自定义BuildConfig字段属性
buildConfigField("boolean", "buildConfigBoolean", "true")
buildConfigField("String", "buildConfigString", ""huawei"")
buildConfigField("int", "buildConfigInt", "1")
}
create("xiaomi") {
buildConfigField("boolean", "buildConfigBoolean", "true")
buildConfigField("String", "buildConfigString", ""xiaomi"")
buildConfigField("int", "buildConfigInt", "1")
}
create("other") {
buildConfigField("boolean", "buildConfigBoolean", "true")
buildConfigField("String", "buildConfigString", ""other"")
buildConfigField("int", "buildConfigInt", "1")
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
kotlinOptions {
jvmTarget = '1.8'
}
}
apply from: "../buildReleaseApkFile.gradle"
dependencies {
implementation 'androidx.core:core-ktx:1.7.0'
implementation 'androidx.appcompat:appcompat:1.3.0'
implementation 'com.google.android.material:material:1.4.0'
implementation 'androidx.constraintlayout:constraintlayout:2.0.4'
testImplementation 'junit:junit:4.13.2'
androidTestImplementation 'androidx.test.ext:junit:1.1.3'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
}