构建与部署:Debug/Profile/Release 模式与多渠道打包
mediumflutterbuildreleasedebugprofileflavorobfuscationapp-bundlexcarchiveci-cd
三种构建模式
| 模式 | 编译方式 | DevTools | assert | 使用场景 |
|---|---|---|---|---|
debug |
JIT(边运行边编译) | ✅ 完整 | ✅ 启用 | 日常开发、Hot Reload |
profile |
AOT(提前编译) | ✅ 性能分析 | ❌ | 测量真实性能 |
release |
AOT | ❌ | ❌ | 上架发布 |
flutter run # debug
flutter run --profile # profile
flutter run --release # release
flutter build apk # Android release APK
flutter build appbundle # Android App Bundle(推荐上传 Google Play)
flutter build ipa # iOS release IPA(需 Xcode)
代码混淆与 Size 优化
# 混淆 + 生成符号映射(用于 crash 反混淆)
flutter build appbundle --obfuscate --split-debug-info=./build/debug-info
# 查看包大小分析
flutter build appbundle --analyze-size
混淆后 .dart_tool 目录会生成 app.android-arm64.symbols,上传到 Firebase Crashlytics 可以反解 crash 栈。
Flavor(多渠道/多环境)
典型需求:dev(开发)/staging(测试)/prod(生产)三套配置,不同 appId、不同 API baseUrl、不同图标。
Android Flavor
// android/app/build.gradle
android {
flavorDimensions += "env"
productFlavors {
dev {
dimension "env"
applicationId "com.example.app.dev"
resValue "string", "app_name", "MyApp Dev"
}
prod {
dimension "env"
applicationId "com.example.app"
resValue "string", "app_name", "MyApp"
}
}
}
iOS Scheme
在 Xcode 中添加 Scheme:Product → Scheme → New Scheme,命名为 Runner-dev,设置对应的 Build Configuration(Debug-dev/Release-dev)。
在 Info.plist 中通过 User-Defined Settings 读取不同配置。
Flutter 侧统一入口
// main_dev.dart
void main() {
const config = AppConfig(
env: 'dev',
baseUrl: 'https://dev-api.example.com',
enableLogging: true,
);
runApp(MyApp(config: config));
}
// main_prod.dart
void main() {
const config = AppConfig(
env: 'prod',
baseUrl: 'https://api.example.com',
enableLogging: false,
);
runApp(MyApp(config: config));
}
# 使用 flavor 构建
flutter build apk --flavor dev -t lib/main_dev.dart
flutter build appbundle --flavor prod -t lib/main_prod.dart
CI/CD 自动化(Fastlane + GitHub Actions)
# .github/workflows/deploy.yml
name: Deploy to TestFlight
on:
push:
branches: [main]
jobs:
deploy-ios:
runs-on: macos-latest
steps:
- uses: actions/checkout@v4
- name: Set up Flutter
uses: subosito/flutter-action@v2
with:
flutter-version: '3.22.0'
channel: stable
- name: Install dependencies
run: flutter pub get
- name: Run tests
run: flutter test
- name: Build IPA
run: |
flutter build ipa --release \
--export-options-plist ExportOptions.plist
- name: Upload to TestFlight
env:
APP_STORE_CONNECT_API_KEY: ${{ secrets.ASC_API_KEY }}
run: fastlane ios beta
# ios/fastlane/Fastfile
lane :beta do
build_ios_app(
scheme: "Runner",
configuration: "Release",
export_method: "app-store"
)
upload_to_testflight(
api_key_path: "AuthKey.p8",
skip_waiting_for_build_processing: true
)
end
App Bundle vs APK
| APK | App Bundle | |
|---|---|---|
| 大小 | 较大(包含所有 ABI) | 较小(Google Play 按设备分发) |
| 直接安装 | ✅ | ❌(需 Play 分发) |
| ABI 拆分 | 手动 --split-per-abi |
自动 |
| 推荐场景 | 内测、第三方应用市场 | Google Play |
# APK 按 ABI 分包(减小单包大小)
flutter build apk --split-per-abi
# 生成:
# build/app/outputs/apk/release/app-arm64-v8a-release.apk (~15MB)
# build/app/outputs/apk/release/app-armeabi-v7a-release.apk (~12MB)
常见问题
Q:release 包 crash,debug 没问题?
常见原因:
- 混淆导致反射/序列化失败 → 检查
proguard-rules.pro,保留必要类 assert被禁用后逻辑分支变化--split-per-abi后安装了错误架构包- native 库未包含目标 ABI
Q:如何缩减 Flutter release 包大小?
flutter build appbundle(替代 APK,Play 分发按设备 ABI)- 开启代码压缩:
minifyEnabled true - 移除未使用的字体(在 pubspec 中只声明需要的 font weight)
- 图片使用 WebP 格式
- 使用
--analyze-size找出大文件