Slide 1

Slide 1 text

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

Slide 2

Slide 2 text

What is Android App Bundle? Lagos

Slide 3

Slide 3 text

The Android App Bundle (.aab) is a new upload/publishing format. It mirrors the .apk format with a little bit of ‘stew’ ;)

Slide 4

Slide 4 text

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

Slide 5

Slide 5 text

Image source What’s inside App Bundle?

Slide 6

Slide 6 text

Dynamic Delivery Lagos

Slide 7

Slide 7 text

Dynamic delivery serves only those files to the users which they need and this is what allows us to make apps smaller

Slide 8

Slide 8 text

● 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

Slide 9

Slide 9 text

● 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

Slide 10

Slide 10 text

Image source Screen density Architecture Locale Base APK Configuration APKs

Slide 11

Slide 11 text

Device Configuration = en + xxhdpi + arm64 BASE ARM64 XXHDPI EN

Slide 12

Slide 12 text

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

Slide 13

Slide 13 text

● Using Bundletool ● Google Play console - Internal test track Testing App Bundles * App Bundles are not installable until they are signed

Slide 14

Slide 14 text

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

Slide 15

Slide 15 text

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

Slide 16

Slide 16 text

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

Slide 17

Slide 17 text

Dynamic Features Lagos

Slide 18

Slide 18 text

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

Slide 19

Slide 19 text

● 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

Slide 20

Slide 20 text

20 Image source

Slide 21

Slide 21 text

Getting started with Dynamic Feature Lagos

Slide 22

Slide 22 text

22

Slide 23

Slide 23 text

23

Slide 24

Slide 24 text

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

Slide 25

Slide 25 text

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

Slide 26

Slide 26 text

26 module/src/AndroidManifest.xml : you can provide your feature module’s title and other configurations Generated content

Slide 27

Slide 27 text

27 module/src/AndroidManifest.xml dist:onDemand=”true/false”: indication that this module is only available to the user when the user requests from the application Generated content

Slide 28

Slide 28 text

28 module/src/AndroidManifest.xml : indication that this module should be available to Pre L devices at first installation Generated content

Slide 29

Slide 29 text

Installing Dynamic Feature in app Lagos

Slide 30

Slide 30 text

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

Slide 31

Slide 31 text

31 //create splitInstallManager val manager = SplitInstallManagerFactory.create(this)

Slide 32

Slide 32 text

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

Slide 33

Slide 33 text

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()

Slide 34

Slide 34 text

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 {}

Slide 35

Slide 35 text

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 -> {} } } }

Slide 36

Slide 36 text

36 //register the listener manager.registerListener(listener) //unregister the listener manager.unregisterListener(listener)

Slide 37

Slide 37 text

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 {}

Slide 38

Slide 38 text

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

Slide 39

Slide 39 text

Lagos Thank you! Omolara Adejuwon, Brainspace VG @_larikraun