release编译:flutter android编译release版

1. 概述

debug是用来调试的版本,会输出很多日志,加载不必要的插件,release版中会去掉这些内容,使app更稳定,更小,更快。

Flutter官网:Preparing an Android app for release

Flutter中文网: 发布Android版APP

2. 添加启动图标

2.1 启动图标设计规范

Material Design product icons guidelines

2.2 启动图标存储位置

<app dir>/android/app/src/main/res/通过不同的文件夹,区分屏幕分表率

Android手机屏幕标准 对应图标尺寸标准 屏幕密度 比例
xxxhdpi 3840*2160 192*192 640
xxhdpi 1920*1080 144*144 480
xhdpi 1280*720 96*96 320
hdpi 480*800 72*72 240
mdpi 480*320 48*48 160
ldpi 320*240 36*36 120

2.3 修改AndroidManifest

android/app/src/main/AndroidManifest.xml

<application
        android:name="io.flutter.app.FlutterApplication"
        android:label="flutter_example"
        android:icon="@mipmap/ic_launcher">
</application>

其中
android:icon="@mipmap/ic_launcher"为关联的图标名

2.4 验证是否替换成功

启动模拟器查看

icon替换

3. App认证

3.1 创建key

Mac/Linux

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

Windows

keytool -genkey -v -keystore c:/Users/USER_NAME/key.jks -storetype JKS -keyalg RSA -keysize 2048 -validity 10000 -alias key

3.2 添加key.properties

storePassword=<password from previous step>
keyPassword=<password from previous step>
keyAlias=key
storeFile=<location of the key store file, such as /Users/<user name>/key.jks>

不要把key.properties放到共有代码中

3.3 修正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 file(keystoreProperties['storeFile'])
           storePassword keystoreProperties['storePassword']
       }
   }
   buildTypes {
       release {
           signingConfig signingConfigs.release
       }
   }

4. 启用规则缩小apk大小

4.1 创建规则

/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.**  { *; }
-dontwarn io.flutter.embedding.**

4.2 app关联规则

/android/app/build.gradle

android {

    ...

    buildTypes {

        release {

            signingConfig signingConfigs.release

            minifyEnabled true
            useProguard true

            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'

        }
    }
}

5. 额外项检查

5.1 外网访问权限

<app dir>/android/app/src/main/AndroidManifest.xml添加
<uses-permission android:name="android.permission.INTERNET"/>

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.kaisawind.flutter_example">

    <!-- io.flutter.app.FlutterApplication is an android.app.Application that
         calls FlutterMain.startInitialization(this); in its onCreate method.
         In most cases you can leave this as-is, but you if you want to provide
         additional functionality it is fine to subclass or reimplement
         FlutterApplication and put your custom class here. -->
    <uses-permission android:name="android.permission.INTERNET"/>
    <application
        android:name="io.flutter.app.FlutterApplication"
        android:label="flutter_example"
        android:icon="@mipmap/ic_launcher">
        <activity
            android:name=".MainActivity"
            android:launchMode="singleTop"
            android:theme="@style/LaunchTheme"
            android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
            android:hardwareAccelerated="true"
            android:windowSoftInputMode="adjustResize">
            <!-- This keeps the window background of the activity showing
                 until Flutter renders its first frame. It can be removed if
                 there is no splash screen (such as the default splash screen
                 defined in @style/LaunchTheme). -->
            <meta-data
                android:name="io.flutter.app.android.SplashScreenUntilFirstFrame"
                android:value="true" />
            <intent-filter>
                <action android:name="android.intent.action.MAIN"/>
                <category android:name="android.intent.category.LAUNCHER"/>
            </intent-filter>
        </activity>
    </application>
</manifest>

5.2 app名

android:label="flutter_example"为app名称

<application
        android:name="io.flutter.app.FlutterApplication"
        android:label="flutter_example"
        android:icon="@mipmap/ic_launcher">
</application>

5.3 检查编译配置项

<app dir>/android/app/build.gradle

    defaultConfig {
        // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
        applicationId "com.kaisawind.flutter_example"
        minSdkVersion 16
        targetSdkVersion 28
        versionCode flutterVersionCode.toInteger()
        versionName flutterVersionName
        testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
    }
  • applicationId: 唯一的appID

6. 编译release版本

6.1 flutter编译

apk拆分

flutter build apk --split-per-abi

output

  • <app dir>/build/app/outputs/apk/release/app-armeabi-v7a-release.apk
  • <app dir>/build/app/outputs/apk/release/app-arm64-v8a-release.apk

多合一版本

flutter build apk

output

  • <app dir>/build/app/outputs/apk/release/app-release.apk

6.2 Android Studio编译

  • 从项目中打开Android Studio

Android
Android

  • 配置编译选项

[Build]-[Generate Signed Bundle/APK]
Android
Android
Android

output

  • <app dir>/android/app/release/app-release.apk

转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 wind.kaisa@gmail.com

💰

×

Help us with donation