Android 项目中 Gradle 配置实战:多渠道打包、签名配置、版本管理
在 Android 项目开发中,Gradle 配置是实现多渠道打包、签名管理和版本控制的核心。下面我将为你提供一套实战级别的 Gradle 配置方案,涵盖这些关键功能。
1. 项目级 build.gradle 配置
首先是项目根目录下的 build.gradle
文件,主要负责依赖管理和仓库配置:
// 项目级 build.gradle
buildscript {ext {// 全局定义依赖版本,便于统一管理kotlin_version = '1.8.0'gradle_version = '7.4.2'androidx_core = '1.9.0'// 其他常用库版本...}repositories {google()mavenCentral()// 如需使用其他仓库// jcenter() // 注意jcenter已废弃}dependencies {classpath "com.android.tools.build:gradle:$gradle_version"classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"// 用于多渠道打包的插件classpath 'com.google.gms:google-services:4.3.15'// 其他插件...}
}allprojects {repositories {google()mavenCentral()// 其他仓库...}
}// 清理任务
task clean(type: Delete) {delete rootProject.buildDir
}
2. 模块级 build.gradle 配置
这是 app 模块下的 build.gradle
文件,包含了多渠道、签名和版本管理的核心配置:
plugins {id 'com.android.application'id 'kotlin-android'// 多渠道打包支持id 'com.google.gms.google-services'
}// 签名配置
android {// 签名配置signingConfigs {// 发布环境签名release {// 从gradle.properties读取敏感信息,避免硬编码storeFile file(RELEASE_STORE_FILE)storePassword RELEASE_STORE_PASSWORDkeyAlias RELEASE_KEY_ALIASkeyPassword RELEASE_KEY_PASSWORD// 启用V2签名v2SigningEnabled true// 启用签名压缩enableV2SigningCompression true}// 调试环境签名debug {// 通常使用Android Studio默认的调试签名storeFile file('debug.keystore')storePassword 'android'keyAlias 'androiddebugkey'keyPassword 'android'}}// 编译配置compileSdk 33buildToolsVersion '33.0.1'// 默认配置defaultConfig {applicationId "com.example.myapp"minSdk 21targetSdk 33versionCode 101 // 版本号,用于Google Play更新判断versionName "1.0.1" // 版本名称,显示给用户// 应用名称字符串资源resValue "string", "app_name", "My Application"// 测试配置testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"// 多Dex支持multiDexEnabled true// 默认渠道manifestPlaceholders = [CHANNEL_NAME: "default"]}// 多渠道配置flavorDimensions "channel"productFlavors {// 应用商店渠道googlePlay {dimension "channel"manifestPlaceholders = [CHANNEL_NAME: "google_play"]// 可以为特定渠道定义不同的applicationId// applicationIdSuffix ".google"}huawei {dimension "channel"manifestPlaceholders = [CHANNEL_NAME: "huawei"]}xiaomi {dimension "channel"manifestPlaceholders = [CHANNEL_NAME: "xiaomi"]}oppo {dimension "channel"manifestPlaceholders = [CHANNEL_NAME: "oppo"]}vivo {dimension "channel"manifestPlaceholders = [CHANNEL_NAME: "vivo"]}// 自定义渠道enterprise {dimension "channel"manifestPlaceholders = [CHANNEL_NAME: "enterprise"]// 企业版可以有不同的版本号versionCode defaultConfig.versionCode + 100}}// 构建类型配置buildTypes {release {minifyEnabled true // 启用代码混淆shrinkResources true // 移除未使用资源proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'signingConfig signingConfigs.release// 配置输出APK名称applicationVariants.all { variant ->variant.outputs.each { output ->def outputFile = output.outputFileif (outputFile != null && outputFile.name.endsWith('.apk')) {// 输出格式: app-渠道-版本名称-版本号-发布时间.apkdef fileName = "app-${variant.flavorName}-v${defaultConfig.versionName}-${defaultConfig.versionCode}-${new Date().format('yyyyMMdd')}.apk"output.outputFileName = fileName}}}// 定义构建变量buildConfigField("boolean", "ENABLE_LOG", "false")buildConfigField("String", "API_URL", "\"https://api.example.com/prod/\"")}debug {minifyEnabled falsedebuggable truesigningConfig signingConfigs.debug// 配置输出APK名称applicationVariants.all { variant ->variant.outputs.each { output ->def outputFile = output.outputFileif (outputFile != null && outputFile.name.endsWith('.apk')) {def fileName = "app-${variant.flavorName}-debug-v${defaultConfig.versionName}-${defaultConfig.versionCode}.apk"output.outputFileName = fileName}}}// 定义构建变量buildConfigField("boolean", "ENABLE_LOG", "true")buildConfigField("String", "API_URL", "\"https://api.example.com/dev/\"")}// 自定义构建类型 - 测试环境staging {initWith release // 继承release的配置minifyEnabled false // 测试环境不混淆debuggable truesigningConfig signingConfigs.debugbuildConfigField("boolean", "ENABLE_LOG", "true")buildConfigField("String", "API_URL", "\"https://api.example.com/staging/\"")}}// 编译选项compileOptions {sourceCompatibility JavaVersion.VERSION_11targetCompatibility JavaVersion.VERSION_11}kotlinOptions {jvmTarget = '11'}// 资源配置sourceSets {main {java.srcDirs = ['src/main/java']res.srcDirs = ['src/main/res']assets.srcDirs = ['src/main/assets']}// 可以为不同渠道配置不同的资源目录enterprise {res.srcDirs = ['src/enterprise/res']}}// 打包选项packagingOptions {exclude 'META-INF/LICENSE'exclude 'META-INF/LICENSE.txt'exclude 'META-INF/NOTICE.txt'}
}// 依赖配置
dependencies {implementation fileTree(dir: 'libs', include: ['*.jar'])// AndroidX核心库implementation "androidx.core:core-ktx:$androidx_core"implementation 'androidx.appcompat:appcompat:1.6.1'implementation 'com.google.android.material:material:1.9.0'implementation 'androidx.constraintlayout:constraintlayout:2.1.4'// 多Dex支持implementation 'androidx.multidex:multidex:2.0.1'// 测试依赖testImplementation 'junit:junit:4.13.2'androidTestImplementation 'androidx.test.ext:junit:1.1.5'androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1'
}
3. 签名信息配置
为了安全起见,签名信息不应硬编码在 build.gradle 中,而是放在 gradle.properties
文件中:
# 签名配置信息
RELEASE_STORE_FILE=/path/to/your/release.keystore
RELEASE_STORE_PASSWORD=your_store_password
RELEASE_KEY_ALIAS=your_key_alias
RELEASE_KEY_PASSWORD=your_key_password# 可以添加其他全局配置
android.useAndroidX=true
android.enableJetifier=true
4. ProGuard 混淆配置
在 proguard-rules.pro
文件中配置代码混淆规则:
# 基础混淆配置
-optimizationpasses 5
-dontusemixedcaseclassnames
-dontskipnonpubliclibraryclasses
-dontpreverify
-verbose
-optimizations !code/simplification/arithmetic,!field/*,!class/merging/*# 保留基本组件
-keep public class * extends android.app.Activity
-keep public class * extends android.app.Application
-keep public class * extends android.app.Service
-keep public class * extends android.content.BroadcastReceiver
-keep public class * extends android.content.ContentProvider
-keep public class * extends android.app.backup.BackupAgentHelper
-keep public class * extends android.preference.Preference# 保留native方法
-keepclasseswithmembernames class * {native <methods>;
}# 保留自定义控件
-keepclasseswithmembers class * {public <init>(android.content.Context, android.util.AttributeSet);
}# 保留枚举
-keepclassmembers enum * {public static **[] values();public static** valueOf(java.lang.String);
}# 保留Parcelable
-keep class * implements android.os.Parcelable {public static final android.os.Parcelable$Creator *;
}# 保留R文件
-keepclassmembers class **.R$* {public static <fields>;
}# 忽略警告
-dontwarn android.support.**
-dontwarn org.apache.**# 保留特定库
-keep class com.google.** { *; }
-dontwarn com.google.**
5. 多渠道打包命令
配置完成后,可以使用以下命令进行多渠道打包:
# 生成所有渠道的release版本
./gradlew assembleRelease# 生成特定渠道的release版本
./gradlew assembleGooglePlayRelease
./gradlew assembleHuaweiRelease# 生成所有渠道的debug版本
./gradlew assembleDebug# 生成特定渠道的staging版本
./gradlew assembleXiaomiStaging
打包完成的 APK 文件会输出到 app/build/outputs/apk/
目录下,文件名包含了渠道、版本等信息,便于识别和分发。
这种配置方案的优势在于:
- 版本号和版本名称集中管理,便于维护
- 签名信息安全存储,避免泄露
- 不同渠道可以有不同的配置和资源
- 不同构建类型(release/debug/staging)可以有不同的行为
- 输出的 APK 文件名包含关键信息,便于管理
根据实际项目需求,你可以进一步扩展这个配置,例如添加更多渠道、自定义更多构建类型或添加更多的构建变量。