Build and release an Android app

Contents
  • Calculation a launcher icon
  • Enabling Cloth 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 back up
  • Reviewing the app manifest
  • Reviewing the Gradle build configuration
    • Under the defaultConfig block
    • Under the android cake
  • Building the app for release
    • Build an app parcel
    • Test the app packet
      • 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 fat APK?
    • What are the supported target architectures?
    • How practice I sign the app package created by flutter build appbundle?
    • How do I build a release from inside Android Studio?

During a typical evolution cycle, you test an app using flutter run at the command 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 set to ready a release version of your app, for example to publish to the Google Play Shop, this folio can aid. Before publishing, you lot might want to put some finishing touches on your app. This page covers the following topics:

  • Calculation 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
  • Edifice 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 Palpitate app is created, it has a default launcher icon. To customize this icon, you might want to check out the flutter_launcher_icons packet.

Alternatively, you tin can do it manually using the following steps:

  1. Review the Material Design production icons guidelines for icon blueprint.

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

  3. In AndroidManifest.xml, update the application tag'due south android:icon attribute to reference icons from the previous step (for instance, <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 may want to enable Cloth Components by following the steps described in the Getting Started guide for Android.

For example:

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

To observe out the latest version, visit Google Maven.

  1. Set the light theme in <my-app>/android/app/src/principal/res/values/styles.xml:
                          -<way name="NormalTheme" parent="@android:style/Theme.Calorie-free.NoTitleBar">                            +<style name="NormalTheme" parent="Theme.MaterialComponents.Lite.NoActionBar">                                    
  1. Set the dark theme in <my-app>/android/app/src/primary/res/values-night/styles.xml
                          -<style name="NormalTheme" parent="@android:style/Theme.Blackness.NoTitleBar">                            +<style name="NormalTheme" parent="Theme.MaterialComponents.DayNight.NoActionBar">                                    

Signing the app

To publish on the Play Store, you need to requite your app a digital signature. Use the following instructions to sign your app.

On Android, there are two signing keys: deployment and upload. The end-users download the .apk signed with the 'deployment key'. An 'upload key' is used to authenticate the .aab / .apk uploaded by developers onto the Play Store and is re-signed with the deployment key in one case in the Play Store.

  • It's highly recommended to employ the automated deject managed signing for the deployment key. For more information, run across the official Play Shop documentation.

Create an upload keystore

If you accept an existing keystore, skip to the adjacent stride. If not, create ane by either:

  • Following the Android Studio central generation steps
  • Running the following at the command line:

    On Mac/Linux, use the following command:

                                                          keytool -genkey -five -keystore ~/upload-keystore.jks -keyalg RSA -keysize 2048 -validity 10000 -alias 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 -alias upload                                                

    This command stores the upload-keystore.jks file in your home directory. If yous want to shop it elsewhere, change the argument you laissez passer to the -keystore parameter. However, keep the keystore file individual; don't check information technology into public source control!

Reference the keystore from the app

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

            storePassword=<countersign from previous stride> keyPassword=<password from previous footstep> keyAlias=upload storeFile=<location of the fundamental shop file, such equally /Users/<user name>/upload-keystore.jks>                      

Configure signing in gradle

Configure gradle to employ your upload central when building your app in release manner past editing the [project]/android/app/build.gradle file.

  1. Add the keystore information from your properties file earlier the android cake:

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

    Load the key.properties file into the keystoreProperties object.

  2. Notice the buildTypes block:

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

    And supercede it with the following signing configuration info:

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

Release builds of your app will now be signed automatically.

For more data on signing your app, see Sign your app on developer.android.com.

Shrinking your code with R8

R8 is the new code shrinker from Google, and it's enabled by default when y'all build a release APK or AAB. To disable R8, laissez passer the --no-shrink flag to flutter build apk or flutter build appbundle.

Enabling multidex support

When writing large apps or making apply of large plugins, you may run across Android'due south dex limit of 64k methods when targeting a minimum API of twenty or below. This may also be encountered when running debug versions of your app via flutter run that does not have 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 Flutter to automatically depend on androidx.multidex:multidex and use a generated FlutterMultiDexApplication as the project's application.

You lot might also choose to manually support multidex by following Android'southward guides and modifying your project'due south Android directory configuration. A multidex go on file must exist specified to include:

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

As well, include any other classes used in app startup. See the official Android documentation for more detailed guidance on calculation multidex support manually.

Reviewing the app manifest

Review the default App Manifest file, AndroidManifest.xml, located in [project]/android/app/src/chief and verify that the values are correct, especially the following:

application
Edit the android:label in the application tag to reflect the final proper name of the app.
uses-permission
Add together the android.permission.Net permission if your awarding code needs Internet admission. The standard template does not include this tag only allows Internet access during evolution to enable communication between Flutter 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 right:

Under the defaultConfig cake

applicationId
Specify the final, unique application ID
minSdkVersion
Specify the minimum API level on which the app is designed to run. Defaults to flutter.minSdkVersion.
targetSdkVersion
Specify the target API level on which the app is designed to run. Defaults to palpitate.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 higher numbers indicating more contempo versions. This version isn't shown to users.
versionName
A string used equally the version number shown to users. This setting tin can be specified as a raw string or as a reference to a string resources.
buildToolsVersion
If y'all're using Android plugin for Gradle three.0.0 or higher, your project automatically uses the default version of the build tools that the plugin specifies. Alternatively, you can specify a version of the build tools.

Under the android block

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

For more than information, run into the module-level build department in the Gradle build file.

Building the app for release

You lot accept two possible release formats when publishing to the Play Store.

  • App bundle (preferred)
  • APK

Build an app bundle

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

From the command line:

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

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

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

Test the app package

An app bundle can be tested in multiple means—this section describes ii.

Offline using the parcel tool

  1. If y'all haven't done then already, download bundletool from the GitHub repository.
  2. Generate a ready 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 rail, or the alpha or beta channels to test the package before releasing information technology in production.
  2. Follow these steps to upload your parcel to the Play Shop.

Build an APK

Although app bundles are preferred over APKs, there are stores that don't notwithstanding 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 will be signed. At this betoken, yous might consider obfuscating your Dart code to make it more than difficult to opposite engineer. Obfuscating your code involves adding a couple flags to your build command.

From the command line:

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

This control results in three APK files:

  • [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

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

Install an APK on a device

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

From the control line:

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

Publishing to the Google Play Store

For detailed instructions on publishing your app to the Google Play Shop, run into the Google Play launch documentation.

Updating the app's version number

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

version: 1.0.0+ane

The version number is iii numbers separated by dots, such as i.0.0 in the example above, followed by an optional build number such every bit ane in the example above, separated by a +.

Both the version and the build number may exist overridden in Flutter's 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 than data, see Version your app in the Android documentation.

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

Android release FAQ

Here are some commonly asked questions about deployment for Android apps.

When should I build app bundles versus APKs?

The Google Play Store recommends that y'all deploy app bundles over APKs considering they allow a more efficient delivery of the application to your users. However, if you lot're distributing your application by ways other than the Play Store, an APK may be your only option.

What is a fat APK?

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

What are the supported target architectures?

When building your awarding in release mode, Palpitate apps tin can be compiled for armeabi-v7a (ARM 32-bit), arm64-v8a (ARM 64-chip), and x86-64 (x86 64-bit). Flutter does non currently support building for x86 Android (Encounter Issue 9253).

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

Come across Signing the app.

How exercise I build a release from within Android Studio?

In Android Studio, open the existing android/ folder under your app's folder. Then, select build.gradle (Module: app) in the project panel:

screenshot of gradle build script menu

Next, select the build variant. Click Build > Select Build Variant in the main menu. Select any of the variants in the Build Variants panel (debug is the default):

screenshot of build variant menu

The resulting app bundle or APK files are located in build/app/outputs within your app'southward binder.