Flutter app打包跟常规打包是差不多的,以android
为例:
这一步呢主要是检查配置app的基础信息:
有keystore
就跳过,没有就执行:
keytool -genkey -v -keystore ~/key.jks -keyalg RSA -keysize 2048 -validity 10000 -alias key
这一步是在 项目/android/app/build.gradle
文件中配置签名信息。
官方的是创建一个key.properties
文件,其实也可以不创建,打开build.gradle
文件,下面是默认创建的模板:
def localProperties = new Properties()
def localPropertiesFile = rootProject.file('local.properties')
if (localPropertiesFile.exists()) {
localPropertiesFile.withReader('UTF-8') { reader ->
localProperties.load(reader)
}
}
...
def flutterVersionCode = localProperties.getProperty('flutter.versionCode')
if (flutterVersionCode == null) {
flutterVersionCode = '1'
}
...
可以看到flutterVersionCode
参数是从local.properties
文件中取的,local.properties:
sdk.dir=E:\\AndroidSDK
flutter.sdk=D:\\flutter\\flutter_windows_v1.7.8+hotfix.4-beta\\flutter
flutter.buildMode=release
flutter.versionName=1.0.0
flutter.versionCode=1
只有5行参数,而新增的配置信息也只有4行而已,我本来是写在一起的,但是属于本地文件不会提交,而且为了区分,还是新建一个key.properties
文件:
storeFile=D:/FlutterProjects/wanandroid_flutter/android/key/key.jks
storePassword=wanandroid
keyAlias=key
keyPassword=wanandroid
然后配置build.gradle
文件:
def localProperties = new Properties()
def localPropertiesFile = rootProject.file('local.properties')
if (localPropertiesFile.exists()) {
localPropertiesFile.withReader('UTF-8') { reader ->
localProperties.load(reader)
}
}
def keystoreProperties = new Properties()
def keystorePropertiesFile = rootProject.file('key.properties')
if (keystorePropertiesFile.exists()) {
keystoreProperties.load(new FileInputStream(keystorePropertiesFile))
}
...
apply plugin: 'com.android.application'
apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle"
android {
compileSdkVersion 28
...
//配置keystore签名
signingConfigs {
release {
keyAlias keystoreProperties['keyAlias']
keyPassword keystoreProperties['keyPassword']
storeFile file(keystoreProperties['storeFile'])
storePassword keystoreProperties['storePassword']
}
debug {
}
}
buildTypes {
release {
signingConfig signingConfigs.release
}
debug {
signingConfig signingConfigs.debug
}
}
}
...
新增了对key.properties
文件的引用(上面第二段代码),新增了signingConfigs
代码块,然后在buildTypes
中引用了一下。
自此,配置的工作就做完了。
默认情况下 flutter 不会开启 Android 的混淆。(可选)
创建/android/app/proguard-rules.pro
文件,并添加以下规则:
#Flutter Wrapper
-keep class io.flutter.app.** { *; }
-keep class io.flutter.plugin.** { *; }
-keep class io.flutter.util.** { *; }
-keep class io.flutter.view.** { *; }
-keep class io.flutter.** { *; }
-keep class io.flutter.plugins.** { *; }
修改build.gradle
文件,这一步跟常规配置一致
android {
...
buildTypes {
release {
signingConfig signingConfigs.release
minifyEnabled true
useProguard true
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
在项目的根目录下执行flutter build apk
。
打开android studio
底部的terminal
窗口默认即当前项目的根目录。
打包过程中稍微等一会,完成之后apk的路径就是上图中下面的路径,/build/app/outputs/apk/app-release.apk
。
到此整个打包流程就结束了。
中间遇到一个报错,具体没记录
flutter.bat finished with non-zero exit value 1
这个问题出现在,修改完build.gradle文件之后,重新构建时提示的。然后还生成了一个flutter_01.log
文件,打开有这么一段:
## exception
FileSystemException: FileSystemException: Failed to decode data using encoding 'utf-8', path = 'D:\FlutterProjects\wanandroid_flutter\android\local.properties'
原来是我local.properties
文件中写了中文注释,导致了编码问题,去掉就好了。
提示这个说明环境变量没配置好,因为我手动升级过一次flutter sdk,现在是1.7
的,但是用户环境中还是1.5
的,所以手动修改之后重启即可。
flutter android 打包流程参考官方文档
ios打包流程由于appleId的限制,就不举例了,跟常规是差不多的,可以参考官方文档