要測試應用,您可以在命令列中使用 flutter run,或在 IDE 中使用 **Run** 和 **Debug** 選項。

當您準備好構建應用的釋出版本時,例如為了釋出到 Google Play 商店,此頁面將有所幫助。在釋出之前,您可能需要對您的應用進行一些最後的潤飾。本指南將介紹如何執行以下任務:

新增啟動器圖示

#

當建立一個新的 Flutter 應用時,它會有一個預設的啟動器圖示。要自定義此圖示,您可能需要檢視 flutter_launcher_icons 包。

或者,您也可以手動完成,方法如下:

  1. 請參閱 Material Design 產品圖示指南以瞭解圖示設計。

  2. [project]/android/app/src/main/res/ 目錄中,將您的圖示檔案放在使用配置限定符命名的資料夾中。預設的 mipmap- 資料夾展示了正確的命名約定。

  3. AndroidManifest.xml 中,更新 application 標籤的 android:icon 屬性,使其指向前一步中的圖示(例如,<application android:icon="@mipmap/ic_launcher" ...)。

  4. 要驗證圖示是否已替換,請執行您的應用並在啟動器中檢查應用圖示。

啟用 Material Components

#

如果您的應用使用了平臺檢視,您可能需要按照Android 的 Material Components 入門指南中的步驟啟用 Material Components。

例如

  1. <my-app>/android/app/build.gradle.kts 中新增 Android 的 Material 依賴項。

    groovy
    dependencies {
        // ...
        implementation("com.google.android.material:material:<version>")
        // ...
    }

    要查詢最新版本,請訪問 Google Maven

  2. <my-app>/android/app/src/main/res/values/styles.xml 中設定淺色主題。

    xml
    <style name="NormalTheme" parent="@android:style/Theme.Light.NoTitleBar">
    <style name="NormalTheme" parent="Theme.MaterialComponents.Light.NoActionBar">
  3. <my-app>/android/app/src/main/res/values-night/styles.xml 中設定深色主題。

    xml
    <style name="NormalTheme" parent="@android:style/Theme.Black.NoTitleBar">
    <style name="NormalTheme" parent="Theme.MaterialComponents.DayNight.NoActionBar">

簽名應用

#

要在 Play 商店釋出,您需要使用數字證書對您的應用進行簽名。

Android 使用兩種簽名金鑰:上傳金鑰和應用簽名金鑰。

  • 開發者將使用上傳金鑰簽名的 .aab.apk 檔案上傳到 Play 商店。
  • 終端使用者下載的是使用應用簽名金鑰簽名的 .apk 檔案。

要建立您的應用簽名金鑰,請使用官方 Play 商店文件中描述的 Play 應用簽名。

要簽名您的應用,請遵循以下說明。

建立上傳金鑰庫

#

如果您已有金鑰庫,請跳到下一步。如果沒有,請使用以下方法之一建立:

  1. 遵循Android Studio 金鑰生成步驟

  2. 在命令列中執行以下命令:

    在 macOS 或 Linux 上,使用以下命令:

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

    在 Windows 上,在 PowerShell 中使用以下命令:

    keytool -genkey -v -keystore $env:USERPROFILE\upload-keystore.jks `
            -storetype JKS -keyalg RSA -keysize 2048 -validity 10000 `
            -alias upload

    此命令將 upload-keystore.jks 檔案儲存在您的主目錄中。如果您想將其儲存在其他位置,請更改傳遞給 -keystore 引數的引數。但是,請務必將 keystore 檔案設為私有;不要將其檢入公共原始碼控制!

從應用引用金鑰庫

#

建立一個名為 [project]/android/key.properties 的檔案,其中包含對您的金鑰庫的引用。不要包含尖括號(< >)。它們表示該文字是您值的佔位符。

properties
storePassword=<password-from-previous-step>
keyPassword=<password-from-previous-step>
keyAlias=upload
storeFile=<keystore-file-location>

storeFile 可能位於 macOS 上的 /Users/<user name>/upload-keystore.jks 或 Windows 上的 C:\\Users\\<user name>\\upload-keystore.jks

在 Gradle 中配置簽名

#

在釋出模式下構建應用時,配置 Gradle 以使用您的上傳金鑰。要配置 Gradle,請編輯 <project>/android/app/build.gradle.kts 檔案。

  1. android 屬性塊之前定義並載入金鑰庫屬性檔案。

  2. keystoreProperties 物件設定為載入 key.properties 檔案。

    [project]/android/app/build.gradle.kts
    kotlin
    import java.util.Properties
    import java.io.FileInputStream
    
    plugins {
       ...
    }
    
    val keystoreProperties = Properties()
    val keystorePropertiesFile = rootProject.file("key.properties")
    if (keystorePropertiesFile.exists()) {
        keystoreProperties.load(FileInputStream(keystorePropertiesFile))
    }
    
    android {
       ...
    }
  3. android 屬性塊內的 buildTypes 屬性塊之前添加簽名配置。

    [project]/android/app/build.gradle.kts
    kotlin
    android {
        // ...
    
        signingConfigs {
            create("release") {
                keyAlias = keystoreProperties["keyAlias"] as String
                keyPassword = keystoreProperties["keyPassword"] as String
                storeFile = keystoreProperties["storeFile"]?.let { file(it) }
                storePassword = keystoreProperties["storePassword"] as String
            }
        }
        buildTypes {
            release {
                // TODO: Add your own signing config for the release build.
                // Signing with the debug keys for now,
                // so `flutter run --release` works.
                signingConfig = signingConfigs.getByName("debug")
                signingConfig = signingConfigs.getByName("release")
            }
        }
    ...
    }

Flutter 現在將簽名所有釋出版本。

要了解有關簽名應用的更多資訊,請檢視 Android 開發者文件中的簽名您的應用

使用 R8 縮減程式碼

#

R8 是 Google 的新程式碼縮減器。當您構建釋出版 APK 或 AAB 時,它預設啟用。要停用 R8,請將 --no-shrink 標誌傳遞給 flutter build apkflutter build appbundle

啟用 multidex 支援

#

在編寫大型應用或使用大型外掛時,當目標最低 API 為 20 或更低時,您可能會遇到 Android 的 64k 方法限制。在使用不啟用縮減的 flutter run 除錯版本執行時,也可能遇到此問題。

Flutter 工具支援輕鬆啟用 multidex。最簡單的方法是在提示時選擇啟用 multidex 支援。該工具會檢測 multidex 構建錯誤,並在更改 Android 專案之前徵求您的意見。選擇啟用後,Flutter 會自動依賴 androidx.multidex:multidex,並使用生成的 FlutterMultiDexApplication 作為專案的應用。

當您嘗試使用 IDE 中的 **Run** 和 **Debug** 選項構建和執行應用時,您的構建可能會失敗並顯示以下訊息:

Build failure because Multidex support is required

要從命令列啟用 multidex,請執行 flutter run --debug 並選擇一個 Android 裝置。

Selecting an Android device with the flutter CLI.

出現提示時,輸入 y。Flutter 工具將啟用 multidex 支援並重試構建。

The output of a successful build after adding multidex.

您也可以選擇手動支援 multidex,方法是遵循 Android 的指南並修改您專案的 Android 目錄配置。必須指定一個multidex 保持檔案以包含

io/flutter/embedding/engine/loader/FlutterLoader.class
io/flutter/util/PathUtils.class

另外,請包含在應用啟動過程中使用的任何其他類。有關手動新增 multidex 支援的更詳細指南,請檢視官方 Android 文件

檢視應用清單

#

檢視預設的應用清單檔案。

[project]/android/app/src/main/AndroidManifest.xml
xml
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
    <application
        android:label="[project]"
        ...
    </application>
    ...
    <uses-permission android:name="android.permission.INTERNET"/>
</manifest>

驗證以下值:

標籤屬性
application編輯 application 標籤中的 android:label 以反映應用的最終名稱。
uses-permission如果您的應用需要網際網路訪問,請將 android.permission.INTERNET 許可權值新增到 android:name 屬性。標準模板不包含此標籤,但在開發期間允許網際網路訪問,以啟用 Flutter 工具和正在執行的應用之間的通訊。

檢視或更改 Gradle 構建配置

#

要驗證 Android 構建配置,請檢視預設 Gradle 構建指令碼中的 android 塊。預設的 Gradle 構建指令碼位於 [project]/android/app/build.gradle.kts。您可以更改任何這些屬性的值。

[project]/android/app/build.gradle.kts
kotlin
android {
    namespace = "com.example.[project]"
    // Any value starting with "flutter." gets its value from
    // the Flutter Gradle plugin.
    // To change from these defaults, make your changes in this file.
    compileSdk = flutter.compileSdkVersion
    ndkVersion = flutter.ndkVersion

    ...

    defaultConfig {
        // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
        applicationId = "com.example.[project]"
        // You can update the following values to match your application needs.
        minSdk = flutter.minSdkVersion
        targetSdk = flutter.targetSdkVersion
        // These two properties use values defined elsewhere in this file.
        // You can set these values in the property declaration
        // or use a variable.
        versionCode = flutterVersionCode.toInteger()
        versionName = flutterVersionName
    }

    buildTypes {
        ...
    }
}

在 build.gradle.kts 中要調整的屬性

#
屬性用途預設值
compileSdk您的應用是針對哪個 Android API 級別編譯的。這應該是可用的最高版本。如果您將此屬性設定為 31,只要您的應用不使用 31 特有的 API,您就可以在執行 API 30 或更低版本的裝置上執行您的應用。
defaultConfig
.applicationId標識您應用的最終、唯一應用 ID
.minSdk您為其設計了應用以執行的最低 Android API 級別flutter.minSdkVersion
.targetSdk您測試應用執行的 Android API 級別。您的應用應在此級別之前的所有 Android API 級別上執行。flutter.targetSdkVersion
.versionCode一個正整數,用於設定內部版本號。此數字僅用於確定哪個版本比另一個版本更新。較大的數字表示較新的版本。應用使用者永遠看不到此值。
.versionName一個字串,您的應用將其顯示為版本號。將此屬性設定為原始字串或對字串資源的引用。
.buildToolsVersionGradle 外掛指定了您的專案使用的 Android 構建工具的預設版本。要指定不同的構建工具版本,請更改此值。

要了解有關 Gradle 的更多資訊,請檢視 Gradle 構建檔案中關於模組級別構建的部分。

構建釋出版應用

#

釋出到 Play 商店時,您有兩種可能的釋出格式。

  • 應用捆綁包(推薦)
  • APK

構建應用捆綁包

#

本節介紹如何構建釋出版應用捆綁包。如果您已完成簽名步驟,應用捆綁包將已簽名。此時,您可能需要考慮混淆您的 Dart 程式碼,使其更難被反編譯。混淆程式碼涉及向構建命令新增標誌並維護其他檔案以反混淆堆疊跟蹤。

從命令列

  1. 輸入 cd [project]
  2. 執行 flutter build appbundle
    (執行 flutter build 預設為釋出版本。)

您應用的釋出捆綁包建立在 [project]/build/app/outputs/bundle/release/app.aab

預設情況下,應用捆綁包包含您的 Dart 程式碼以及為 armeabi-v7a(ARM 32 位)、arm64-v8a(ARM 64 位)和 x86-64(x86 64 位)編譯的 Flutter 執行時。

測試應用捆綁包

#

應用捆綁包可以透過多種方式進行測試。本節介紹兩種方法。

離線使用 bundle tool

#
  1. 如果您尚未完成,請從其GitHub 倉庫下載 bundletool
  2. 從您的應用捆綁包生成一組 APK
  3. 將 APK 部署到連線的裝置。

線上使用 Google Play

#
  1. 將您的捆綁包上傳到 Google Play 進行測試。您可以使用內部測試軌道,或 Alpha 或 Beta 頻道,在生產環境中釋出之前測試捆綁包。
  2. 按照上傳捆綁包的步驟將其上傳到 Play 商店。

構建 APK

#

儘管應用捆綁包比 APK 更受歡迎,但有些商店尚未支援應用捆綁包。在這種情況下,為每個 ABI(應用程式二進位制介面)構建一個釋出版 APK。

如果您已完成簽名步驟,APK 將已簽名。此時,您可能需要考慮混淆您的 Dart 程式碼,使其更難被反編譯。混淆程式碼涉及向構建命令新增標誌。

從命令列

  1. 輸入 cd [project]

  2. 執行 flutter build apk --split-per-abi。(flutter build 命令預設為 --release。)

此命令將生成三個 APK 檔案:

  • [project]/build/app/outputs/apk/release/app-armeabi-v7a-release.apk
  • [project]/build/app/outputs/apk/release/app-arm64-v8a-release.apk
  • [project]/build/app/outputs/apk/release/app-x86_64-release.apk

移除 --split-per-abi 標誌將生成一個“fat”APK,其中包含為您所有目標 ABI 編譯的程式碼。這些 APK 比其拆分版本更大,導致使用者在安裝您的應用程式時下載不適用於其裝置架構的原生二進位制檔案。

在裝置上安裝 APK

#

按照以下步驟將 APK 安裝到連線的 Android 裝置上。

從命令列

  1. 使用 USB 資料線將您的 Android 裝置連線到計算機。
  2. 輸入 cd [project]
  3. 執行 flutter install

釋出到 Google Play 商店

#

有關將應用釋出到 Google Play 商店的詳細說明,請檢視 Google Play 啟動文件。

更新應用的 versionCode

#

應用的預設版本號是 1.0.0。要更新它,請導航到 pubspec.yaml 檔案並更新以下行:

yaml
version: 1.0.0+1

版本號是由點分隔的三個數字,例如上面示例中的 1.0.0,後跟一個可選的構建號,例如上面示例中的 1,用 + 分隔。

透過指定 --build-name--build-number,可以在 Flutter 構建中分別覆蓋版本和構建號。

在 Android 中,build-name 用作 versionName,而 build-number 用作 versionCode。有關更多資訊,請檢視 Android 文件中的版本化您的應用

當您為 Android 重新構建應用時,pubspec 檔案中版本號的任何更新都將更新 local.properties 檔案中的 versionNameversionCode

Android 釋出常見問題解答

#

以下是關於 Android 應用部署的一些常見問題。

何時應構建應用捆綁包而不是 APK?

#

Google Play 商店建議您部署應用捆綁包而不是 APK,因為它們可以更有效地將應用程式交付給使用者。但是,如果您透過 Play 商店以外的渠道分發您的應用程式,APK 可能是您唯一的選擇。

什麼是“fat”APK?

#

一個“fat”APK是包含嵌入其中的多個 ABI 的二進位制檔案的單個 APK。其優點是單個 APK 可以在多個架構上執行,因此具有更廣泛的相容性,但缺點是檔案尺寸大得多,導致使用者在安裝您的應用程式時下載和儲存更多位元組。在構建 APK 而不是應用捆綁包時,強烈建議構建拆分 APK,如構建 APK部分中所述,使用 --split-per-abi 標誌。

支援的目標架構有哪些?

#

在釋出模式下構建應用程式時,Flutter 應用可以編譯為 armeabi-v7a(ARM 32 位)、arm64-v8a(ARM 64 位)和 x86-64(x86 64 位)。

如何簽名由 flutter build appbundle 建立的應用捆綁包?

#

請參閱簽名應用

如何在 Android Studio 中構建釋出版?

#

在 Android Studio 中,開啟您應用資料夾下的現有 android/ 資料夾。然後在專案面板中選擇 **build.gradle (Module: app)**。

The Gradle build script menu in Android Studio.

接下來,選擇構建變體。在主選單中單擊 **Build > Select Build Variant**。在 **Build Variants** 面板中選擇任何一個變體(debug 是預設值)。

The build variant menu in Android Studio with Release selected.

生成的應用捆綁包或 APK 檔案位於您應用資料夾內的 build/app/outputs