Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Diving into Android App Bundle

Diving into Android App Bundle

Android app bundle (.aab) it's a new publishing format for android apps. This presentation handles all that is involved from dynamic delivery, split APKs, bundletool and dynamic features.


Omolara Adejuwon

November 03, 2018


  1. Omolara Adejuwon, Brainspace VG @_larikraun Lagos Diving into Android App

  2. What is Android App Bundle? Lagos

  3. The Android App Bundle (.aab) is a new upload/publishing format.

    It mirrors the .apk format with a little bit of ‘stew’ ;)
  4. What is the need? • It makes the support of

    different configurations better - Dynamic delivery • Your users have a smaller APK to download • It favors modularization i.e cleaner code base • Leads us to dynamic features • Google Play console handles the serving for you Lagos
  5. Image source What’s inside App Bundle?

  6. Dynamic Delivery Lagos

  7. Dynamic delivery serves only those files to the users which

    they need and this is what allows us to make apps smaller
  8. • A fundamental component of Dynamic Delivery. • Available on

    L+. • With split APKs Google Play can break up a large app into smaller packages that are installed on a user's device based on device’s configuration Split APKs
  9. • Base APK: contains all common code and resources •

    Configuration APKs: contains resources based on device’s config i.e locale, architecture, screen density • Dynamic Feature APKs: contains codes that can be downloaded at a later time. This will be discussed later in the presentation. 3 Kinds of Split APKs
  10. Image source Screen density Architecture Locale Base APK Configuration APKs

  11. Device Configuration = en + xxhdpi + arm64 BASE ARM64

  12. 12 android{ ... bundle { language { /* This property

    is set to true by default. Specifies that the app bundle should not support configuration APKs for language resources. These resources are instead packaged with each base and dynamic feature APK.*/ enableSplit = false } density { enableSplit = true } abi { enableSplit = true } } } Version 3.2+ + /app/build.gradle
  13. • Using Bundletool • Google Play console - Internal test

    track Testing App Bundles * App Bundles are not installable until they are signed
  14. 14 java -jar bundletool build-apks --bundle=PATH_TO_APP_BUNDLE \ --output=PATH_TO_OUTPUT_APKS --ks=PATH_TO_KEYSTORE \

    --ks-pass=pass:KEYSTORE_PASSWORD --ks-key-alias=KEY_ALIAS \ --key-pass=pass:KEY_PASSWORD --overwrite Bundletool -> Generate APKs http://github.com/google/bundletool https://developer.android.com/studio/command-line/bundletool
  15. 15 java -jar bundletool install-apks --apks=PATH_TO_OUTPUT_APKS Bundletool -> Install on

    connected device http://github.com/google/bundletool https://developer.android.com/studio/command-line/bundletool
  16. Enroll in Google Play App Signing Create and manage your

    releases - upload app bundle Google Play serves APKs to devices as required Publishing App Bundles
  17. Dynamic Features Lagos

  18. It allows you break your app into modules/features. Your app

    handles the download and installation of each module when the user needs it. The core of this mechanism is the Play core library. This further helps your initial app size really small
  19. • How many % of your users really need that

    feature? • How large is the feature? • Can your users wait a few seconds to download that feature? When to use dynamic features
  20. 20 Image source

  21. Getting started with Dynamic Feature Lagos

  22. 22

  23. 23

  24. app/build.gradle dynamicFeatures = [":module_one",":module_two"] Generated content

  25. module/build.gradle apply plugin: 'com.android.dynamic-feature' dependencies { ... implementation project(':app') }

    Generated content
  26. 26 module/src/AndroidManifest.xml <dist:module </dist:module> <dist:module/>: you can provide your feature

    module’s title and other configurations Generated content
  27. 27 module/src/AndroidManifest.xml <dist:module dist:onDemand="true" </dist:module> dist:onDemand=”true/false”: indication that this module

    is only available to the user when the user requests from the application Generated content
  28. 28 module/src/AndroidManifest.xml <dist:module dist:onDemand="true" dist:title="@string/module_name"> <dist:fusing dist:include="true"/> </dist:module> <dist:fusing dist:include=”true/false”/>:

    indication that this module should be available to Pre L devices at first installation Generated content
  29. Installing Dynamic Feature in app Lagos

  30. app/build.gradle api 'com.google.android.play:core:1.3.5' Play core library makes it possible to

    install and manage modules
  31. 31 //create splitInstallManager val manager = SplitInstallManagerFactory.create(this)

  32. 32 val manager = SplitInstallManagerFactory.create(this) //check if module has already

    been installed if (manager.installedModules.contains(module_name)) { //load the module }
  33. 33 val manager = SplitInstallManagerFactory.create(this) if (manager.installedModules.contains(module_name)) { //load the

    module } // Create request to install a feature module by name. val request = SplitInstallRequest.newBuilder() .addModule(module_name) .build()
  34. 34 val manager = SplitInstallManagerFactory.create(this) if (manager.installedModules.contains(module_name)) { //load the

    module } // Create request to install a feature module by name. val request = SplitInstallRequest.newBuilder() .addModule(module_name) .build() // Load and install the requested feature module. manager.startInstall(request) .addOnSuccessListener {} .addOnFailureListener {}
  35. 35 val listener = SplitInstallStateUpdatedListener { state -> state.moduleNames().forEach {

    name -> // Handle changes in state. when (state.status()) { SplitInstallSessionStatus.DOWNLOADING -> {} SplitInstallSessionStatus.REQUIRES_USER_CONFIRMATION -> { /*This may occur when attempting to download a large module like 10MB */ startIntentSender(state.resolutionIntent()?.intentSender, null, 0, 0, 0) } SplitInstallSessionStatus.INSTALLED -> {} SplitInstallSessionStatus.INSTALLING -> {} SplitInstallSessionStatus.FAILED -> {} } } }
  36. 36 //register the listener manager.registerListener(listener) //unregister the listener manager.unregisterListener(listener)

  37. 37 //defer installation of some modules manager.deferredInstall(modules).addOnSuccessListener {} //uninstall modules

    that are no more needed val installedModules = manager.installedModules.toList() manager.deferredUninstall(installedModules).addOnSuccessListener {}
  38. 38 • https://developer.android.com/studio/projects/dynamic-delivery • https://developer.android.com/studio/command-line/bundletool • https://events.google.com/io/schedule/?section=may-8&sid=b9ea bde0-be05-492c-bf9e-c3f772f1db7e • https://codelabs.developers.google.com/codelabs/your-first-dyn

    amic-app/index.html Useful Resources
  39. Lagos Thank you! Omolara Adejuwon, Brainspace VG @_larikraun