Build and release an Android app

Contents
  • Calculation a launcher icon
  • Enabling Material Components
  • Signing the app
    • Create an upload keystore
    • Reference the keystore from the app
    • Configure signing in gradle
  • Shrinking your code with R8
  • Enabling multidex support
  • Reviewing the app manifest
  • Reviewing the Gradle build configuration
    • Nether the defaultConfig block
    • Under the android cake
  • Edifice the app for release
    • Build an app bundle
    • Test the app bundle
      • Offline using the package tool
      • Online using Google Play
    • Build an APK
    • Install an APK on a device
  • Publishing to the Google Play Store
  • Updating the app's version number
  • Android release FAQ
    • When should I build app bundles versus APKs?
    • What is a fatty APK?
    • What are the supported target architectures?
    • How practise I sign the app package created by flutter build appbundle?
    • How do I build a release from within Android Studio?

During a typical development cycle, you test an app using flutter run at the control line, or by using the Run and Debug options in your IDE. By default, Flutter builds a debug version of your app.

When y'all're ready to prepare a release version of your app, for example to publish to the Google Play Store, this page tin aid. Earlier publishing, you might want to put some finishing touches on your app. This page covers the post-obit topics:

  • Adding a launcher icon
  • Enabling Cloth Components
  • Signing the app
  • Shrinking your code with R8
  • Enabling multidex support
  • Reviewing the app manifest
  • Reviewing the build configuration
  • Building the app for release
  • Publishing to the Google Play Shop
  • Updating the app's version number
  • Android release FAQ

Adding a launcher icon

When a new Flutter app is created, it has a default launcher icon. To customize this icon, yous might want to cheque out the flutter_launcher_icons package.

Alternatively, you can practise it manually using the post-obit steps:

  1. Review the Cloth Design product icons guidelines for icon blueprint.

  2. In the [project]/android/app/src/principal/res/ directory, identify your icon files in folders named using configuration qualifiers. The default mipmap- folders demonstrate the correct naming convention.

  3. In AndroidManifest.xml, update the awarding tag's android:icon attribute to reference icons from the previous step (for example, <application android:icon="@mipmap/ic_launcher" ...).

  4. To verify that the icon has been replaced, run your app and inspect the app icon in the Launcher.

Enabling Material Components

If your app uses Platform Views, you lot may desire to enable Material Components by following the steps described in the Getting Started guide for Android.

For instance:

  1. Add the dependency on Android's Cloth in <my-app>/android/app/build.gradle:
                          dependencies              {              // ...              implementation              'com.google.android.material:cloth:<version>'              // ...              }                      

To find out the latest version, visit Google Maven.

  1. Set the light theme in <my-app>/android/app/src/primary/res/values/styles.xml:
                          -<style name="NormalTheme" parent="@android:way/Theme.Light.NoTitleBar">                            +<style proper noun="NormalTheme" parent="Theme.MaterialComponents.Light.NoActionBar">                                    
  1. Set up the dark theme in <my-app>/android/app/src/main/res/values-night/styles.xml
                          -<mode name="NormalTheme" parent="@android:fashion/Theme.Black.NoTitleBar">                            +<style name="NormalTheme" parent="Theme.MaterialComponents.DayNight.NoActionBar">                                    

Signing the app

To publish on the Play Shop, yous need to give your app a digital signature. Employ the following instructions to sign your app.

On Android, there are ii signing keys: deployment and upload. The terminate-users download the .apk signed with the 'deployment key'. An 'upload key' is used to authenticate the .aab / .apk uploaded past developers onto the Play Store and is re-signed with the deployment primal once in the Play Store.

  • Information technology'southward highly recommended to use the automatic deject managed signing for the deployment central. For more information, see the official Play Store documentation.

Create an upload keystore

If you take an existing keystore, skip to the next step. If non, create ane by either:

  • Following the Android Studio key generation steps
  • Running the post-obit at the command line:

    On Mac/Linux, apply the post-obit command:

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

    On Windows, use the following command:

                                                          keytool -genkey -v -keystore c:\Users\USER_NAME\upload-keystore.jks -storetype JKS -keyalg RSA -keysize 2048 -validity 10000 -allonym upload                                                

    This command stores the upload-keystore.jks file in your home directory. If you desire to store it elsewhere, change the argument yous pass to the -keystore parameter. However, go along the keystore file private; don't check it into public source command!

Reference the keystore from the app

Create a file named [project]/android/key.properties that contains a reference to your keystore:

            storePassword=<password from previous pace> keyPassword=<countersign from previous step> keyAlias=upload storeFile=<location of the key store file, such equally /Users/<user proper name>/upload-keystore.jks>                      

Configure signing in gradle

Configure gradle to apply your upload fundamental when building your app in release mode by editing the [project]/android/app/build.gradle file.

  1. Add the keystore data from your backdrop file before the android block:

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

    Load the primal.properties file into the keystoreProperties object.

  2. Find the buildTypes block:

                                      buildTypes {        release {            // TODO: Add your own signing config for the release build.            // Signing with the debug keys for now,            // then `flutter run --release` works.            signingConfig signingConfigs.debug        }    }                              

    And supersede it with the following signing configuration info:

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

Release builds of your app volition now be signed automatically.

For more information on signing your app, meet Sign your app on developer.android.com.

Shrinking your lawmaking with R8

R8 is the new lawmaking shrinker from Google, and it's enabled by default when you lot build a release APK or AAB. To disable R8, pass the --no-shrink flag to flutter build apk or flutter build appbundle.

Enabling multidex support

When writing large apps or making use of big plugins, you may encounter Android's dex limit of 64k methods when targeting a minimum API of xx or below. This may as well be encountered when running debug versions of your app via flutter run that does non accept shrinking enabled.

Flutter tool supports easily enabling multidex. The simplest way is to opt into multidex support when prompted. The tool detects multidex build errors and will ask before making changes to your Android project. Opting in allows Palpitate to automatically depend on androidx.multidex:multidex and utilize a generated FlutterMultiDexApplication as the projection'south application.

Y'all might also cull to manually support multidex by following Android's guides and modifying your project'due south Android directory configuration. A multidex keep file must be specified to include:

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

Also, include whatsoever other classes used in app startup. See the official Android documentation for more detailed guidance on adding multidex support manually.

Reviewing the app manifest

Review the default App Manifest file, AndroidManifest.xml, located in [projection]/android/app/src/main and verify that the values are correct, especially the post-obit:

awarding
Edit the android:characterization in the application tag to reflect the final proper noun of the app.
uses-permission
Add together the android.permission.Cyberspace permission if your application code needs Internet access. The standard template does non include this tag simply allows Internet access during development to enable communication between Palpitate tools and a running app.

Reviewing the Gradle build configuration

Review the default Gradle build file (build.gradle) located in [project]/android/app to verify the values are correct:

Nether the defaultConfig block

applicationId
Specify the terminal, unique awarding ID
minSdkVersion
Specify the minimum API level on which the app is designed to run. Defaults to palpitate.minSdkVersion.
targetSdkVersion
Specify the target API level on which the app is designed to run. Defaults to flutter.targetSdkVersion.
versionCode
A positive integer used as an internal version number. This number is used only to determine whether one version is more recent than another, with college numbers indicating more recent versions. This version isn't shown to users.
versionName
A string used as the version number shown to users. This setting can be specified as a raw string or as a reference to a cord resource.
buildToolsVersion
If you're using Android plugin for Gradle 3.0.0 or higher, your project automatically uses the default version of the build tools that the plugin specifies. Alternatively, y'all can specify a version of the build tools.

Under the android cake

compileSdkVersion
Specify the API level Gradle should apply to compile your app. Defaults to palpitate.compileSdkVersion.

For more than information, meet the module-level build section in the Gradle build file.

Building the app for release

You have 2 possible release formats when publishing to the Play Shop.

  • App bundle (preferred)
  • APK

Build an app bundle

This section describes how to build a release app package. If you completed the signing steps, the app bundle will be signed. At this signal, you might consider obfuscating your Dart code to make information technology more difficult to contrary engineer. Obfuscating your code involves adding a couple flags to your build command, and maintaining boosted files to de-obfuscate stack traces.

From the control line:

  1. Enter cd [project]
  2. Run palpitate build appbundle
    (Running flutter build defaults to a release build.)

The release bundle for your app is created at [project]/build/app/outputs/bundle/release/app.aab.

By default, the app packet contains your Sprint code and the Flutter runtime compiled for armeabi-v7a (ARM 32-scrap), arm64-v8a (ARM 64-chip), and x86-64 (x86 64-bit).

Test the app parcel

An app bundle can exist tested in multiple ways—this section describes ii.

Offline using the bundle tool

  1. If you haven't done so already, download bundletool from the GitHub repository.
  2. Generate a set of APKs from your app bundle.
  3. Deploy the APKs to connected devices.

Online using Google Play

  1. Upload your bundle to Google Play to test it. You can use the internal test track, or the alpha or beta channels to exam the bundle earlier releasing information technology in production.
  2. Follow these steps to upload your bundle to the Play Store.

Build an APK

Although app bundles are preferred over APKs, in that location are stores that don't yet support app bundles. In this case, build a release APK for each target ABI (Application Binary Interface).

If you completed the signing steps, the APK volition be signed. At this point, you might consider obfuscating your Dart code to make information technology more difficult to opposite engineer. Obfuscating your lawmaking involves calculation a couple flags to your build control.

From the control line:

  1. Enter cd [projection]
  2. Run flutter build apk --split-per-abi
    (The flutter build command defaults to --release.)

This command results in three APK files:

  • [projection]/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

Removing the --divide-per-abi flag results in a fat APK that contains your lawmaking compiled for all the target ABIs. Such APKs are larger in size than their split counterparts, causing the user to download native binaries that are not applicative to their device'southward architecture.

Install an APK on a device

Follow these steps to install the APK on a connected Android device.

From the control line:

  1. Connect your Android device to your calculator with a USB cable.
  2. Enter cd [project].
  3. Run flutter install.

Publishing to the Google Play Shop

For detailed instructions on publishing your app to the Google Play Store, encounter the Google Play launch documentation.

Updating the app's version number

The default version number of the app is 1.0.0. To update it, navigate to the pubspec.yaml file and update the following line:

version: ane.0.0+one

The version number is 3 numbers separated by dots, such as i.0.0 in the instance above, followed past an optional build number such as 1 in the example in a higher place, separated by a +.

Both the version and the build number may be overridden in Flutter'due south build by specifying --build-name and --build-number, respectively.

In Android, build-name is used as versionName while build-number used as versionCode. For more information, meet Version your app in the Android documentation.

Afterwards updating the version number in the pubspec file, run flutter pub get from the top of the project, or utilise the Pub get button in your IDE. This updates the versionName and versionCode in the local.backdrop file, which are afterwards updated in the build.gradle file when you rebuild the Flutter app.

Android release FAQ

Here are some commonly asked questions well-nigh deployment for Android apps.

When should I build app bundles versus APKs?

The Google Play Store recommends that you deploy app bundles over APKs because they allow a more efficient commitment of the awarding to your users. However, if you're distributing your awarding past means other than the Play Store, an APK may be your merely option.

What is a fat APK?

A fat APK is a single APK that contains binaries for multiple ABIs embedded within information technology. This has the benefit that the single APK runs on multiple architectures and thus has wider compatibility, only it has the drawback that its file size is much larger, causing users to download and store more than bytes when installing your application. When building APKs instead of app bundles, information technology is strongly recommended to build split APKs, every bit described in build an APK using the --split-per-abi flag.

What are the supported target architectures?

When building your application in release mode, Flutter apps can be compiled for armeabi-v7a (ARM 32-bit), arm64-v8a (ARM 64-bit), and x86-64 (x86 64-chip). Flutter does not currently back up building for x86 Android (See Issue 9253).

How do I sign the app parcel created by flutter build appbundle?

See Signing the app.

How do I build a release from within Android Studio?

In Android Studio, open up the existing android/ folder nether your app'due south folder. Then, select build.gradle (Module: app) in the projection panel:

screenshot of gradle build script menu

Next, select the build variant. Click Build > Select Build Variant in the primary carte du jour. Select any of the variants in the Build Variants console (debug is the default):

screenshot of build variant menu

The resulting app packet or APK files are located in build/app/outputs inside your app's folder.