Android 签名与打包
生成 keystore、理解 Android 的 V1/V2/V3 签名方案,以及使用 Android Studio 或 Gradle 命令行打出可通过蒲公英分发的 APK。
Android 要求所有应用在安装前都经过数字签名,签名同时决定了后续版本能否被视为"同一个应用"并覆盖升级。本文介绍如何生成签名证书、打包 APK,以及在通过蒲公英分发时需要留意的事项。
调试签名与正式签名
Android Studio 会自动使用调试签名来运行本地开发构建;对外分发则需要您自行生成并长期保管的正式签名。
| 类型 | 来源 | 适用场景 |
|---|---|---|
| 调试签名(Debug) | Android Studio 自动生成于 ~/.android/debug.keystore | 本地开发、真机调试 |
| 正式签名(Release) | 开发者使用 keytool 手动生成,需离线备份 | 通过蒲公英分发、上架应用市场 |
蒲公英不会校验 APK 使用的签名类型,调试签名的包也能上传。但测试者如果先装了调试版,再安装正式版时会因签名不一致而被系统拒绝覆盖安装。建议从一开始就使用正式签名向测试者分发。
生成 keystore
使用 JDK 自带的 keytool 命令即可生成一个可长期使用的 keystore 文件:
keytool -genkeypair -v \
-keystore my-release-key.jks \
-keyalg RSA -keysize 2048 -validity 10000 \
-alias my-alias| 参数 | 说明 |
|---|---|
-keystore | 生成的 keystore 文件名 |
-keyalg | 密钥算法,推荐 RSA |
-keysize | 密钥长度,推荐 2048 或更高 |
-validity | 有效期(天),建议至少 10000(约 27 年) |
-alias | 密钥别名,打包时需要引用 |
执行过程中会提示输入 keystore 密码、别名密码以及组织信息,请使用密码管理器妥善保存。
keystore 文件与密码一旦丢失将无法找回,此后您无法再为同一包名(applicationId)的应用发布任何更新——Android 系统会拒绝用另一个签名的 APK 覆盖已安装的应用。请离线备份 keystore,并将密码与主干代码分开存储。
签名方案 V1 / V2 / V3 / V4
Android 先后推出了四代签名方案,新方案向后兼容旧系统,并不互相取代:
| 方案 | 引入版本 | 说明 |
|---|---|---|
| V1(JAR Signature) | 早期版本 | 对 APK 内文件逐个签名,兼容最广 |
| V2(APK Signature Scheme v2) | Android 7.0 | 对整个 APK 文件签名,安装更快、防篡改更强 |
| V3 | Android 9.0 | 在 V2 基础上支持密钥轮换 |
| V4 | Android 11 | 生成独立的 .idsig 文件,用于增量安装场景 |
推荐同时启用 V1 + V2(Android Studio 的默认行为),以兼顾老系统和较强的完整性校验。
使用 Android Studio 打包
- 菜单栏选择 Build → Generate Signed Bundle / APK。
- 选择 APK(不要选 Android App Bundle,见下文)。
- 选择已有 keystore 或点击 Create new 新建,填入别名与密码。
- Build Variants 选择
release,Signature Versions 勾选 V1 与 V2。 - 完成后可在模块目录下的
app/release/中找到签名后的 APK。
使用 Gradle 命令行打包
在 app/build.gradle 中配置签名信息:
android {
signingConfigs {
release {
storeFile file("my-release-key.jks")
storePassword System.getenv("KEYSTORE_PASSWORD")
keyAlias "my-alias"
keyPassword System.getenv("KEY_PASSWORD")
}
}
buildTypes {
release {
signingConfig signingConfigs.release
minifyEnabled true
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
}然后执行:
./gradlew assembleRelease输出位于 app/build/outputs/apk/release/app-release.apk,可直接上传至蒲公英。
不要将 storePassword / keyPassword 明文写入 build.gradle 并提交到代码仓库。推荐通过环境变量、~/.gradle/gradle.properties 或 CI 的加密凭据注入。
检查 APK 的签名
上传前可使用 Android SDK build-tools 自带的 apksigner 校验签名:
apksigner verify --verbose app-release.apk输出会列出启用的签名方案(V1/V2/V3)以及证书信息。若提示 DOES NOT VERIFY,说明 APK 未签名或签名损坏,需重新打包。
关于 Android App Bundle (AAB)
Android App Bundle (.aab) 是 Google Play 推荐的新发布格式,由 Google Play 根据用户设备动态拆分出对应的 APK。蒲公英目前仅支持 APK 分发,不支持 AAB。 在 Android Studio 的导出对话框中请选择 "APK";若使用 Gradle,请运行 assembleRelease 而非 bundleRelease。
常见问题
安装时提示"签名不一致"或"存在同名应用"?
Android 不允许不同签名的同 applicationId 应用互相覆盖。测试者需要先卸载旧版本再安装新版本。最常见的原因是测试者此前安装过调试签名的版本,后续又收到了正式签名的版本。
正式签名的 APK 上传后下载页提示"未签名"?
请先用 apksigner verify 校验本地 APK 是否真的带有签名。如果命令提示 DOES NOT VERIFY,通常是打包时选错了构建类型(把 debug 当成 release 了),或签名配置未生效。
团队中多人需要打包,keystore 如何共享? 将 keystore 文件存储在团队共享的加密保险库(如 1Password、Bitwarden)中,不要提交到代码仓库。CI 环境下通过加密凭据(GitHub Actions Secret、Jenkins Credentials 等)注入密码与文件,避免明文留存在流水线日志中。