Files

234 lines
5.9 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Android 配置指南
本文档覆盖 Android 端从 Flavor 验证到正式签名发布包所需的全部配置步骤。
---
## 前提
- Android Studio Meerkat (2024.3) 或更高版本
- Android SDKAPI 34compileSdk/ API 21minSdk
- JDK 17Android Gradle Plugin 要求)
- 已完成 [setup-project.md](setup-project.md) 的 Step 14
---
## 1. 验证 Flavor 构建
脚手架预配置了三个 Flavor`dev` / `staging` / `prod`,对应三套应用名和包名后缀。
```bash
# 确认三个 Flavor 都能构建(debug 模式,速度最快)
make build-apk-dev # com.example.sunny_mochi.dev
flutter build apk --flavor staging --debug \
--dart-define-from-file=dart-defines/staging.json
# com.example.sunny_mochi.staging
flutter build apk --flavor prod --debug \
--dart-define-from-file=dart-defines/prod.json
# com.example.sunny_mochi
```
若构建失败,检查 `android/app/build.gradle.kts` 中的 `flavorDimensions``productFlavors` 配置。
---
## 2. 修改包名(业务项目必须)
编辑 `android/app/build.gradle.kts`,找到 `productFlavors``defaultConfig`
```kotlin
defaultConfig {
applicationId = "com.your_company.your_app" // ← 修改
// ...
}
productFlavors {
create("dev") {
applicationIdSuffix = ".dev"
// applicationId 实际为 com.your_company.your_app.dev
resValue("string", "app_name", "YourApp Dev") // ← 修改应用名
}
create("staging") {
applicationIdSuffix = ".staging"
resValue("string", "app_name", "YourApp Beta") // ← 修改应用名
}
create("prod") {
resValue("string", "app_name", "YourApp") // ← 修改应用名
}
}
```
同步修改 `android/app/src/main/AndroidManifest.xml` 确认使用 `@string/app_name`(脚手架默认已使用)。
---
## 3. 配置 Release 签名
### 3.1 生成 Keystore(首次)
```bash
mkdir -p android/keystore
keytool -genkey -v \
-keystore android/keystore/release.jks \
-alias your-key-alias \
-keyalg RSA \
-keysize 2048 \
-validity 10000
```
> ⚠️ **Keystore 丢失无法找回,必须妥善保管。** 建议:
> - 备份到加密云存储(1Password / Bitwarden Vault
> - CI/CD 系统通过 secret 变量注入,不放在仓库中
> - `android/keystore/` 目录已在 `.gitignore` 中
### 3.2 填写 key.properties
```bash
cp android/key.properties.template android/key.properties
```
编辑 `android/key.properties`(相对于 `android/app/` 目录):
```properties
storePassword=your-keystore-password
keyPassword=your-key-password
keyAlias=your-key-alias
storeFile=../keystore/release.jks
```
> `key.properties` 已在 `android/.gitignore` 中,不会被提交。
### 3.3 验证签名配置
```bash
# 构建 staging release APK(使用 release 签名)
make build-staging
# 查看签名信息
apksigner verify --print-certs \
build/app/outputs/flutter-apk/app-staging-release.apk
```
---
## 4. 配置 Firebase(可选)
若业务项目使用 Firebase(推送通知 / Analytics):
1. 在 [Firebase Console](https://console.firebase.google.com) 为每个 Flavor 创建应用(不同包名)
2. 下载各包名对应的 `google-services.json`,放置到对应 Flavor 目录:
```
android/app/src/
├── dev/google-services.json
├── staging/google-services.json
└── main/google-services.json # prod 用 main
```
3.`android/app/build.gradle.kts` 添加 Google Services 插件:
```kotlin
plugins {
// ...
id("com.google.gms.google-services")
}
```
4.`google-services.json` 加入 `.gitignore`(含 API key,勿提交):
```
# 在根 .gitignore 中添加
**/google-services.json
```
> `google-services.json` 已在 `android/.gitignore` 中有注释行,取消注释即可。
---
## 5. 配置 ProGuard / R8Release 混淆)
脚手架的 `android/app/build.gradle.kts` 已预启用 R8
```kotlin
buildTypes {
release {
isMinifyEnabled = true
proguardFiles(
getDefaultProguardFile("proguard-android-optimize.txt"),
"proguard-rules.pro"
)
}
}
```
`android/app/proguard-rules.pro` 中已预留 Drift / Sentry / Riverpod 保留规则注释,按需取消注释。
---
## 6. SQLCipher 注意事项
脚手架已在 `build.gradle.kts` 中处理 SQLCipher 的 native library 冲突:
```kotlin
packaging {
jniLibs {
pickFirsts += setOf("**/libsqlite3.so")
}
}
```
若后续新增包时出现 `libsqlite3.so` 重复错误,在此处追加相同模式即可。
---
## 7. CI/CD 构建(示例:GitHub Actions
以下为生产包构建的 workflow 关键步骤:
```yaml
- name: Decode keystore
run: |
echo "${{ secrets.KEYSTORE_BASE64 }}" | base64 --decode \
> android/keystore/release.jks
- name: Write key.properties
run: |
cat > android/key.properties <<EOF
storePassword=${{ secrets.KEYSTORE_PASSWORD }}
keyPassword=${{ secrets.KEY_PASSWORD }}
keyAlias=${{ secrets.KEY_ALIAS }}
storeFile=../keystore/release.jks
EOF
- name: Write prod.json
run: |
echo '${{ secrets.PROD_DART_DEFINES }}' > dart-defines/prod.json
- name: Build AAB
run: make build-prod
```
Secrets 清单:`KEYSTORE_BASE64``KEYSTORE_PASSWORD``KEY_PASSWORD``KEY_ALIAS``PROD_DART_DEFINES`
---
## 常见问题
### Gradle sync 失败,报找不到 compileSdk
确认 Android SDK Platform 34 已安装(Android Studio → SDK Manager → Android 14)。
### `libsqlite3.so` duplicate 错误
`build.gradle.kts``packaging.jniLibs.pickFirsts` 中追加冲突的 .so 路径。
### Release APK 运行时崩溃,Debug APK 正常
通常是 ProGuard 混淆了不应混淆的类。查看 `build/outputs/mapping/` 下的 `seeds.txt` 和 Logcat,在 `proguard-rules.pro` 添加对应的 `-keep` 规则。
### 签名 APK 安装时提示"应用已安装但签名不同"
设备上已安装其他签名版本,需先卸载再安装,或换测试设备。