28、发布与打包:签名配置、混淆规则、版本管理、App Bundle与APK、上架Google Play

说实话,写代码写到能打包发布,才算真正走完一个闭环。很多新手觉得「能跑就行」,但真正上线的App,签名、混淆、版本管理这些环节,一个都绕不开。我见过不少项目,开发时一切正常,一打包就崩——嗯,多半是混淆规则没配好。

这一章,咱们就把发布打包这件事彻底讲透。从签名配置到上架Google Play,每一步我都会结合自己的踩坑经验来说。

核心要点:发布打包不是「点一下按钮」那么简单。签名保证身份,混淆保护代码,版本管理控制迭代,App Bundle优化分发。这四个环节环环相扣。

发布与打包 签名配置 混淆规则 版本管理 App Bundle与APK debug/release签名 密钥库管理 签名验证 ProGuard/R8 keep规则 常见坑点 versionCode versionName 版本号策略 AAB vs APK 构建变体 上架流程 签名 → 混淆 → 版本 → 打包 → 上架,一个都不能少

28.1 签名配置:你的App身份证

签名说白了就是给App盖个章。Google Play用它来确认「这个App确实是你的」。我刚开始做Android时,有次不小心丢了密钥库文件——那感觉,就像丢了家门钥匙,只能重新建一个应用。

在Jetpack Compose项目中,签名配置写在build.gradle.kts(Module级别)里。我个人习惯把签名信息单独放在一个keystore.properties文件中,避免硬编码。

// keystore.properties(放在项目根目录)
storePassword=myStorePassword
keyPassword=myKeyPassword
keyAlias=myKeyAlias
storeFile=../my-release-key.jks

然后在build.gradle.kts中读取:

// 在android块外部
val keystorePropertiesFile = rootProject.file("keystore.properties")
val keystoreProperties = java.util.Properties()
keystoreProperties.load(java.io.FileInputStream(keystorePropertiesFile))

android {
    signingConfigs {
        create("release") {
            keyAlias = keystoreProperties["keyAlias"] as String
            keyPassword = keystoreProperties["keyPassword"] as String
            storeFile = file(keystoreProperties["storeFile"] as String)
            storePassword = keystoreProperties["storePassword"] as String
        }
    }
    
    buildTypes {
        release {
            signingConfig = signingConfigs.getByName("release")
            // ...
        }
    }
}

⚠️ 重要提醒:千万不要把keystore.properties提交到Git仓库!在.gitignore中加上它。我曾经见过有人把密钥库传到GitHub上,结果被机器人扫描到,直接盗用签名发布恶意版本。

28.2 混淆规则:保护你的代码

混淆不是为了让代码跑得更快,而是让反编译的人看得更头疼。R8是Android官方推荐的混淆工具,从AGP 3.4.0开始默认启用。

你想想看,如果不做混淆,别人用个反编译工具就能把你的代码看得一清二楚。特别是涉及到API密钥、加密逻辑的时候,混淆是必须的。

build.gradle.kts中启用:

android {
    buildTypes {
        release {
            isMinifyEnabled = true
            isShrinkResources = true
            proguardFiles(
                getDefaultProguardFile("proguard-android-optimize.txt"),
                "proguard-rules.pro"
            )
        }
    }
}

proguard-rules.pro文件里写什么?我总结了几条必加的规则:

# 保留Compose相关类(不混淆会崩)
-keep class androidx.compose.** { *; }

# 保留数据类(序列化用)
-keep class com.yourpackage.model.** { *; }

# 保留Retrofit接口
-keep interface com.yourpackage.api.** { *; }

# 保留枚举类
-keep enum * { *; }

💡 我的经验:每次发布前,先用./gradlew assembleRelease打一个包,安装到手机上跑一遍核心流程。我曾经有一次忘了加Compose的keep规则,结果打包后界面全白——嗯,那叫一个尴尬。

28.3 版本管理:别让用户困惑

版本管理有两个关键字段:versionCodeversionName

字段 类型 作用 示例
versionCode 整数 内部版本号,用于判断更新 28
versionName 字符串 展示给用户看的版本 2.1.0

我个人习惯用语义化版本:主版本.次版本.修订号。比如2.1.0表示第二个大版本的第一次小迭代。每次发布,versionCode加1,versionName按规则更新。

build.gradle.kts中配置:

android {
    defaultConfig {
        applicationId = "com.yourpackage.app"
        versionCode = 28
        versionName = "2.1.0"
    }
}

注意:Google Play要求versionCode必须递增。如果你上传了一个versionCode=28的包,下一个包必须是29或更高。降级是不允许的。

28.4 App Bundle与APK:选哪个?

从2021年8月开始,Google Play要求新应用必须使用App Bundle(AAB)格式发布。APK主要用于内部测试或侧载安装。

说白了,AAB是「智能分发」——Google Play会根据用户的设备配置(屏幕密度、CPU架构、语言等),只下发必要的资源。用户下载的APK会更小,安装更快。

在Android Studio中生成AAB:

# 生成Release AAB
./gradlew bundleRelease

# 生成Release APK
./gradlew assembleRelease

生成的AAB文件在app/build/outputs/bundle/release/目录下,APK在app/build/outputs/apk/release/目录下。

💡 我的建议:开发阶段用APK调试,发布时用AAB上传Google Play。如果你需要给客户演示,也可以打APK直接发给他们安装。

28.5 上架Google Play:最后一步

上架流程其实不复杂,但细节很多。我整理了一个清单:

  1. 注册开发者账号:一次性费用25美元(约180元人民币)
  2. 准备素材:应用图标、截图(至少2张)、特征图、宣传语
  3. 填写商店信息:应用名称、描述、分类、联系方式
  4. 设置定价与分发:免费还是付费?哪些国家可用?
  5. 上传AAB文件:在Google Play Console中上传
  6. 填写版本说明:这次更新了什么?用中文写清楚
  7. 审核与发布:提交后通常几小时到几天不等

⚠️ 避坑指南:我曾经在「内容分级」这一步卡了三天——因为没填隐私政策链接,Google Play一直不给过。记得提前准备好隐私政策页面,哪怕是个简单的HTML也行。

28.6 构建变体:调试与发布分离

实际项目中,我们通常有debugrelease两种构建类型。我个人习惯再加一个staging用于测试环境。

android {
    buildTypes {
        debug {
            isDebuggable = true
            applicationIdSuffix = ".debug"
            versionNameSuffix = "-debug"
        }
        release {
            isDebuggable = false
            isMinifyEnabled = true
            proguardFiles(...)
        }
        create("staging") {
            initWith(getByName("debug"))
            isMinifyEnabled = true
            proguardFiles(...)
            versionNameSuffix = "-staging"
        }
    }
}

这样,同一台手机上可以同时安装debug版和release版,互不干扰。测试的时候用staging版连接测试服务器,发布时用release版连接正式服务器。

核心总结:签名是身份,混淆是护甲,版本是标签,AAB是趋势。把这四样搞明白,你的App就能安全、高效地到达用户手中。


公众号:蓝海资料掘金营,微信deep3321