Build and release an Android app

Contents
  • Calculation a launcher icon
  • Enabling Textile 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 block
  • Building the app for release
    • Build an app bundle
    • Examination the app bundle
      • Offline using the bundle tool
      • Online using Google Play
    • Build an APK
    • Install an APK on a device
  • Publishing to the Google Play Shop
  • 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 do I sign the app package created by flutter build appbundle?
    • How do I build a release from within Android Studio?

During a typical development bike, 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 you're ready to prepare a release version of your app, for example to publish to the Google Play Store, this page can help. Before publishing, you might desire to put some finishing touches on your app. This page covers the following topics:

  • Adding a launcher icon
  • Enabling Material 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 Store
  • Updating the app's version number
  • Android release FAQ

Calculation a launcher icon

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

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

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

  2. In the [project]/android/app/src/main/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 awarding tag'southward android:icon aspect 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 audit the app icon in the Launcher.

Enabling Material Components

If your app uses Platform Views, yous may want to enable Material Components by post-obit the steps described in the Getting Started guide for Android.

For example:

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

To notice out the latest version, visit Google Maven.

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

Signing the app

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

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

  • It'due south highly recommended to utilize the automatic cloud managed signing for the deployment key. For more information, see the official Play Store documentation.

Create an upload keystore

If y'all have an existing keystore, skip to the next pace. If non, create one by either:

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

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

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

    On Windows, use the post-obit control:

                                                          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 you want to store it elsewhere, change the statement you lot laissez passer to the -keystore parameter. However, proceed the keystore file private; don't bank 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 step> keyPassword=<countersign from previous footstep> keyAlias=upload storeFile=<location of the key store file, such equally /Users/<user name>/upload-keystore.jks>                      

Configure signing in gradle

Configure gradle to use your upload key when edifice your app in release mode by editing the [projection]/android/app/build.gradle file.

  1. Add the keystore information from your properties file before the android block:

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

    Load the cardinal.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,            // so `flutter run --release` works.            signingConfig signingConfigs.debug        }    }                              

    And replace information technology with the following signing configuration info:

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

Release builds of your app will now be signed automatically.

For more information on signing your app, meet 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 you build a release APK or AAB. To disable R8, laissez passer the --no-compress flag to flutter build apk or flutter build appbundle.

Enabling multidex back up

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

Palpitate tool supports hands 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 awarding.

You might too choose to manually back up multidex by following Android'due south guides and modifying your project's Android directory configuration. A multidex keep file must exist specified to include:

            io/palpitate/embedding/engine/loader/FlutterLoader.grade io/palpitate/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 [project]/android/app/src/master and verify that the values are correct, especially the following:

application
Edit the android:label in the application tag to reflect the final name of the app.
uses-permission
Add the android.permission.INTERNET permission if your awarding code needs Internet admission. The standard template does not include this tag simply allows Net access during development to enable advice 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:

Under the defaultConfig block

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 but to determine whether i 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 tin can be specified every bit a raw string or as a reference to a string resource.
buildToolsVersion
If you'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, y'all can specify a version of the build tools.

Under the android cake

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

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

Building the app for release

Yous have ii 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 bundle. If you completed the signing steps, the app bundle will exist signed. At this point, you lot might consider obfuscating your Sprint lawmaking to make information technology more difficult to reverse engineer. Obfuscating your code involves calculation a couple flags to your build command, and maintaining additional files to de-obfuscate stack traces.

From the control line:

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

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

By default, the app bundle 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-scrap).

Examination the app bundle

An app packet can exist tested in multiple means—this section describes two.

Offline using the packet tool

  1. If yous oasis't done so already, download bundletool from the GitHub repository.
  2. Generate a ready of APKs from your app bundle.
  3. Deploy the APKs to continued devices.

Online using Google Play

  1. Upload your bundle to Google Play to test information technology. You tin utilize the internal test rail, or the blastoff or beta channels to test the bundle before releasing it in production.
  2. Follow these steps to upload your package to the Play Store.

Build an APK

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

If you lot completed the signing steps, the APK will be signed. At this bespeak, you might consider obfuscating your Dart code to get in more difficult to reverse 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 --split-per-abi
    (The palpitate build control defaults to --release.)

This control results in three APK files:

  • [project]/build/app/outputs/apk/release/app-armeabi-v7a-release.apk
  • [projection]/build/app/outputs/apk/release/app-arm64-v8a-release.apk
  • [projection]/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 split counterparts, causing the user to download native binaries that are not applicable to their device's compages.

Install an APK on a device

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

From the command line:

  1. Connect your Android device to your reckoner with a USB cablevision.
  2. Enter cd [projection].
  3. Run palpitate install.

Publishing to the Google Play Store

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

Updating the app'due south 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: i.0.0+i

The version number is three numbers separated by dots, such as 1.0.0 in the example to a higher place, followed past an optional build number such equally 1 in the example higher up, separated by a +.

Both the version and the build number may be overridden in Flutter'south build past specifying --build-proper noun and --build-number, respectively.

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

After updating the version number in the pubspec file, run palpitate pub get from the pinnacle of the projection, or use the Pub get push in your IDE. This updates the versionName and versionCode in the local.backdrop file, which are later updated in the build.gradle file when you rebuild the Flutter app.

Android release FAQ

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

When should I build app bundles versus APKs?

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

What is a fat APK?

A fatty APK is a single 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, but information technology has the drawback that its file size is much larger, causing users to download and store more than bytes when installing your application. When edifice APKs instead of app bundles, it is strongly recommended to build divide APKs, as described in build an APK using the --split-per-abi flag.

What are the supported target architectures?

When building your application in release manner, Flutter apps tin can be compiled for armeabi-v7a (ARM 32-bit), arm64-v8a (ARM 64-fleck), and x86-64 (x86 64-flake). Palpitate does non currently support building for x86 Android (Meet Event 9253).

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

See Signing the app.

How do I build a release from within Android Studio?

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

screenshot of gradle build script menu

Next, select the build variant. Click Build > Select Build Variant in the chief 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 bundle or APK files are located in build/app/outputs within your app'due south folder.