Photo by Isis França

Generate an Android App Bundle using Xamarin and Azure DevOps

Migrate from apk to Android App Bundle

Posted by Damien Aicheh on February 03, 2020 · 8 mins

Xamarin introduced Android App Bundle support a few weeks ago, it’s now time to take benefit of it!

Why using Android App Bundle?

The Android App Bundle is a package that allows the user to download only what your application needs to run on their devices. For instance, if you have a big resolution for your screen device the application will probably use the resources from the mipmap-xxxhdpi folder so what is the purpose of downloading other resolutions folders? Nothing,it’s useless.

By getting only what you need for your application it will:

  • Download faster
  • Reduce the size of the application on the device
  • Preserve some data from the mobile plan of your users

With that in mind, let’s get started!

Setup your pipeline

Let’s go to Azure DevOps and create a new pipeline.

Inside the Pipelines tab create a New pipeline and follow the 4 steps to get the source code from the correct repository. Azure DevOps will automatically create a new azure-pipelines.yml at the root of your project folder. This is where the job definition will be set and then interpreted by Azure DevOps.

We will need to sign our Android application with a keystore. Create and upload it to the Pipelines > Library > Secure files tab, so it will be accessible by the build agent. In this tutorial the keystore will be named production.jks.

For security reasons we will need to create variables group to store alias and passwords associated to this keystore. If you are not familiar with this you can look at my previous tutorial about it.

For this tutorial, the variable group will be called xamarin-android-aab. You will have only 3 variables inside:

Variable groups

Restore Nugets

We need to restore the Nuget packages of our project and load our variable group:

trigger:
- master

pool:
  vmImage: 'macos-latest'

variables:
  - group: xamarin-android-aab

steps:
- task: NuGetToolInstaller@1

- task: NuGetCommand@2
  inputs:
    restoreSolution: '**/*.sln'

Select Xamarin SDK

To be able to build an Android App Bundle we need to use the latest version of Xamarin SDK available now. To specify it we need to select the correct mono version on our agent. For more detail about choosing your mono version please visit the full Microsoft documentation. Currently the latest version is 6.6.0.

So let’s specify it in our azure-pipelines.yml:

- script: sudo $AGENT_HOMEDIRECTORY/scripts/select-xamarin-sdk.sh 6_6_0
  displayName: "Select the Xamarin SDK version"
  enabled: true

Build our project

With that done, we can now begin building our project. Conventially, when you want to generate an apk for your Xamarin.Android application you use the XamarinAndroid@1 task and the AndroidSigning@3 task to build and sign your package. At the moment, these two tasks combined does not allow you to generate an Android App Bundle. Therefore, Microsoft teams provided a solution: command lines!

To get what we want we will add two tasks:

  • One for downloading the keystore that you use to sign your application
  • One to build and sign the App Bundle package

Go back to your yaml configuration file:

- task: DownloadSecureFile@1
  name: keyStore
  displayName: "Download keystore from secure files"
  inputs:
    secureFile: production.jks

- task: Bash@3
  displayName: "Download keystore from secure files"
  inputs:
    targetType: "inline"
    script: |
      msbuild -restore $(Build.SourcesDirectory)/XamarinAndroidAab/*.csproj -t:SignAndroidPackage -p:AndroidPackageFormat=aab -p:Configuration=$(buildConfiguration) -p:AndroidKeyStore=True -p:AndroidSigningKeyStore=$(keyStore.secureFilePath) -p:AndroidSigningStorePass=$(keystore.password) -p:AndroidSigningKeyAlias=$(key.alias) -p:AndroidSigningKeyPass=$(key.password)

Don’t forget to set the buildConfiguration variable to Release like bellow.

variables:
  - group: xamarin-android-aab
  - name: buildConfiguration
    value: 'Release'

The DownloadSecureFile@1 task allows us to get the keystore from our secure files. With the Bash@3 task we can build our project using msbuild command line. This will sign our application as well, nothing to do more! Notice that the AndroidPackageFormat parameter set the format of the package we need (Android App Bundle), with this value set you don’t need to setup your Xamarin.Android csproj with more options.

Now if you run your job for the first time you will get a warning message asks you to give access to your secure files for the keystore:

Keystore warning

Authorize it by clicking on Permit, and your build will continue to run.

Publish your artifacts

Final step is to get the .aab file generated and published so you can then upload it to the store of your choice.

- task: CopyFiles@2
  displayName: 'Copy deliverables'
  inputs:
    SourceFolder: '$(Build.SourcesDirectory)/XamarinAndroidAab/bin/$(buildConfiguration)'
    Contents: '*.aab'
    TargetFolder: 'drop'

- task: PublishBuildArtifacts@1
  displayName: 'Publish release'
  inputs:
    pathToPublish: 'drop'
    artifactName: 'release'

If everything is done correctly you will be able to download your aab file from Azure DevOps:

Artifacts

Final touch

If you want to generate an apk to check what kind of device configurations your app supports from your app bundle, you can use the bundletool with the following command:

bundletool build-apks --bundle=/path_to/my_app.aab --output=/path_to/my_app.apks

More details about the bundletool are available on the Android documentation.

I created some extensions to help you use bundletool directly in your pipelines, take a look at my tutorial about it.

Sources:

You will find full source code in this Github repository.

Happy coding!

You liked this tutorial? Leave a star in the associated Github repository!

Do not hesitate to follow me on to not miss my next tutorial!