一、准备工作

1.1 环境要求

  • Android Studio(建议最新版)
  • Flutter SDK(已正确配置)
  • Java JDK 11 或更高版本
  • 已配置 Android SDK

1.2 项目准备

在 Android Studio 中打开 Flutter 项目,确保项目能正常运行。

二、生成签名密钥

2.1 使用命令行生成

keytool -genkey -v -keystore ~/upload-keystore.jks -keyalg RSA -keysize 2048 -validity 10000 -alias upload

输入密钥库口令: [输入密码,如:android]
再次输入新口令: [再次输入相同密码]
您的名字与姓氏是什么?
  [Unknown]:  [输入姓名,如:Test]
您的组织单位名称是什么?
  [Unknown]:  [输入部门,如:Dev]
您的组织名称是什么?
  [Unknown]:  [输入公司,如:MyCompany]
您所在的城市或区域名称是什么?
  [Unknown]:  [输入城市,如:Shanghai]
您所在的省/市/自治区名称是什么?
  [Unknown]:  [输入省份,如:Shanghai]
该单位的双字母国家/地区代码是什么?
  [Unknown]:  [输入国家代码,如:CN]
CN=Test, OU=Dev, O=MyCompany, L=Shanghai, ST=Shanghai, C=CN是否正确?
  [否]:  y
  
输入 <upload> 的密钥口令
	(如果和密钥库口令相同, 按回车): [直接按回车]

在这里插入图片描述
在存储位置中

2.2 创建密钥配置文件

在项目 android 目录下创建 key.properties

storePassword=你的密码
keyPassword=你的密码
keyAlias=upload
storeFile=../app/upload-keystore.jks

在这里插入图片描述

三、配置构建文件

3.1 修改 android/app/build.gradle

注意:如果你的文件是 build.gradle.kts(Kotlin DSL),语法不同!

3.2 Groovy DSL(build.gradle):

def keystoreProperties = new Properties()
def keystorePropertiesFile = rootProject.file('key.properties')
if (keystorePropertiesFile.exists()) {
    keystoreProperties.load(new FileInputStream(keystorePropertiesFile))
}

android {
    signingConfigs {
        release {
            keyAlias keystoreProperties['keyAlias']
            keyPassword keystoreProperties['keyPassword']
            storeFile keystoreProperties['storeFile'] ? file(keystoreProperties['storeFile']) : null
            storePassword keystoreProperties['storePassword']
        }
    }
    
    buildTypes {
        release {
            signingConfig signingConfigs.release
            minifyEnabled true
            shrinkResources true
        }
    }
}

3.3 Kotlin DSL(build.gradle.kts):

// === 添加这些导入语句 ===
import com.android.build.api.dsl.ApplicationExtension
import java.io.FileInputStream
import java.util.Properties
// =======================
plugins {
    id("com.android.application")
    id("kotlin-android")
    // The Flutter Gradle Plugin must be applied after the Android and Kotlin Gradle plugins.
    id("dev.flutter.flutter-gradle-plugin")
}
val keystoreProperties = Properties()
val keystorePropertiesFile = rootProject.file("key.properties")
if (keystorePropertiesFile.exists()) {
    keystoreProperties.load(FileInputStream(keystorePropertiesFile))
}

android {
    signingConfigs {
        create("release") {
            keyAlias = keystoreProperties.getProperty("keyAlias")
            keyPassword = keystoreProperties.getProperty("keyPassword")
            storeFile = file(keystoreProperties.getProperty("storeFile"))
            storePassword = keystoreProperties.getProperty("storePassword")
        }
    }
    
    buildTypes {
        getByName("release") {
            isMinifyEnabled = true
            isShrinkResources = true
            signingConfig = signingConfigs.getByName("release")
        }
    }
}

⚠️ 重要区别:Kotlin DSL 使用 isMinifyEnabled,Groovy DSL 使用 minifyEnabled

四、在 Android Studio 中打包

4.1 方法一:使用 Build 菜单(推荐)

  1. 点击顶部菜单 Build
  2. 选择 Flutter
  3. 选择 Build APKBuild App Bundle

4.2 方法二:使用 Gradle 面板

  1. 打开右侧 Gradle 面板
  2. 展开项目 → :app → Tasks → build
  3. 双击 assembleRelease

4.3 方法三:使用 Terminal

在 Android Studio 的 Terminal 中:

flutter build apk --release

在这里插入图片描述

五、APK 输出位置

构建成功后,APK 文件位于:

build/app/outputs/flutter-apk/app-release.apk

或者

android/app/build/outputs/apk/release/app-release.apk

在这里插入图片描述

六、常见错误与解决方案

错误1:Build → Generate Signed Bundle / APK 选项缺失

原因:项目未被正确识别为 Android 项目

解决方案

  1. 在项目面板切换视图为 Android
  2. 或使用命令行:flutter build apk --release
  3. 或右键 android 目录 → Flutter → Open Android Module

错误2:minifyEnabled false 语法错误

错误信息

Unresolved reference: minifyEnabled

原因:混淆了 Groovy 和 Kotlin DSL 语法

解决方案

  • Kotlin DSL:使用 isMinifyEnabled
  • Groovy DSL:使用 minifyEnabled

错误3:签名文件找不到

错误信息

Keystore file '.../key.jks' not found

解决方案

  1. 确保签名文件存在:
ls android/app/*.jks
  1. 检查 key.properties 中的路径是否正确
  2. 或重新生成签名文件

错误4:R8 混淆错误

错误信息

Missing classes detected while running R8

解决方案:添加混淆规则到 android/app/proguard-rules.pro

# Flutter
-keep class io.flutter.app.** { *; }
-keep class io.flutter.plugin.** { *; }
-keep class io.flutter.** { *; }

# 第三方 SDK(如 TradPlus)
-keep class com.tradplus.** { *; }
-keep class com.tp.** { *; }
-dontwarn com.tradplus.**

错误5:APK 文件过大(400+MB)

原因:调试符号未剥离

解决方案

  1. 检查 build.gradle.kts 中是否有:
packaging {
    jniLibs {
        keepDebugSymbols.add("**/libflutter.so")  # ❌ 移除这行!
    }
}
  1. 正确配置:
buildTypes {
    release {
        isMinifyEnabled = true
        isShrinkResources = true
        
        packaging {
            jniLibs {
                keepDebugSymbols.clear()  # ✅ 发布版移除调试符号
            }
        }
    }
}

错误6:Kotlin DSL 赋值错误

错误信息

Assignments are not expressions

原因:赋值语句格式错误

错误示例

keyAlias =  // ❌ 换行了
    keystoreProperties.getProperty("keyAlias")

正确示例

keyAlias = keystoreProperties.getProperty("keyAlias")  // ✅ 一行完成

七、优化建议

7.1 减小 APK 体积

# 分架构打包
flutter build apk --release --split-per-abi

# 只打包 arm64(现代设备)
flutter build apk --release --target-platform android-arm64

7.2 配置 Gradle 优化

android {
    defaultConfig {
        ndk {
            // 只包含主流架构
            abiFilters.addAll(listOf("armeabi-v7a", "arm64-v8a"))
        }
    }
}

7.3 使用 App Bundle

flutter build appbundle --release

八、验证 APK

8.1 检查签名

keytool -printcert -jarfile app-release.apk

8.2 安装测试

adb install app-release.apk

8.3 查看 APK 信息

# 使用 Android Studio 的 APK Analyzer
# Build → Analyze APK...

九、自动化脚本

创建 build_release.sh

#!/bin/bash
echo "🔧 开始构建发布版 APK..."

# 清理
flutter clean

# 获取依赖
flutter pub get

# 构建
flutter build apk --release --split-per-abi

echo "✅ 构建完成!"
echo "📱 APK 位置:"
find build -name "*.apk" -type f | xargs ls -lh

十、经验总结

10.1 关键要点

  1. 区分 DSL:注意 Groovy 和 Kotlin DSL 的语法差异
  2. 签名文件:确保路径正确,文件存在
  3. 调试符号:发布版一定要移除,否则 APK 会巨大
  4. 混淆规则:第三方 SDK 需要添加对应的 keep 规则

10.2 推荐流程

  1. 先测试 Debug 版本能否正常运行
  2. 配置签名和混淆
  3. 构建 Release 版本
  4. 验证 APK 签名和大小
  5. 真机测试

10.3 排错顺序

当遇到构建错误时:

  1. 检查语法(特别是 Kotlin DSL)
  2. 检查文件路径和是否存在
  3. 检查依赖版本兼容性
  4. 查看完整错误日志(--stacktrace

通过本教程,你应该能够顺利完成 Flutter APK 的打包,并避免常见的坑。记住:命令行永远是最可靠的备用方案,当 Android Studio 的 GUI 方法失效时,使用 flutter build apk --release 通常能解决问题。

往期推荐

Android Studio:将 Git 仓库从 HTTP 切换为 SSH 并解决权限问题

本地项目上传GitHub与Android Studio高效Git操作指南

Logo

开源鸿蒙跨平台开发社区汇聚开发者与厂商,共建“一次开发,多端部署”的开源生态,致力于降低跨端开发门槛,推动万物智联创新。

更多推荐