In real life, you’ll probably have many more modules in your app than PetSave has at this point. You might also have some kind of analytics logic in the app, which gives you insight into how users interact with it.
Suppose you have a share animal feature module. This feature allows the user to share an animal’s information on their social networks. Through analytics, you know that this feature is seldom used. However, even users that don’t want to use the feature still install it, taking up precious disk space.
Android app size has a direct relationship to the number of app installs and user retention, with larger apps tending to have fewer installs and lower user retention.
Say that the share animal feature module takes up half the space of the whole app. Wouldn’t it be frustrating to see your app being frequently uninstalled due to a large feature module that almost no one uses?
The Android team is aware of this, so they came up with some mechanisms to mitigate the problem. One of these mechanisms is the app bundle publishing format. Using this publishing format can already help you reduce your app size.
For the most part, however, this chapter focuses on another mechanism: Play Feature Delivery. This mechanism takes advantage of advanced app bundle features to allow you to develop dynamic features.
This chapter is optional if you already know what app bundles and dynamic features are. On the other hand, if you don’t understand those concepts thoroughly yet, what you read here will help.
The chapter focuses on the theoretical side of dynamic features. You’ll learn about:
The app bundle publishing format.
What dynamic features are.
The delivery options for dynamic features.
Two of the most common challenges with dynamic features: dependency injection and navigation.
Android app bundle
Before diving into dynamic features, you need to know about app bundles. An app bundle is Google’s clever app delivery format, which splits the APK into different pieces. It then delivers only the pieces the user’s device requires.
When you upload an APK to Google Play, all users receive that universal APK when they download your app. When you upload an app bundle, however, Google Play uses it to create a few different APKs, called split APKs. These split APKs are available from Android API 21 onwards. There are three different types:
Base APK: Google Play generates this APK from the app module of the app. It contains everything you need to configure and launch the app as well as shared code, in most cases. It’s the first APK that the user downloads and installs.
Configuration APKs: APKs related to different screen densities, languages, CPU architectures or native libraries. When the user downloads the app, Google Play installs only the configuration APKs related to the user’s device.
Dynamic feature APKs: APKs with code and resources for each dynamic feature.
Even if you don’t care about dynamic features, it’s a good idea to use app bundles. If your app is properly modularized, it’ll reduce the final app size. Apart from that, Google is requiring that new apps submitted to Google Play will use app bundles starting from the second half of 2021. Moreover, apps larger than 150 MB will have to use either Play Feature Delivery or Play Asset Delivery.
Play Feature Delivery delivers dynamic features to the user via app bundle features and APIs. You’ll learn more about these later. As for Play Asset Delivery, the logic is the same as Play Feature Delivery, but it applies to game assets.
Dynamic delivery
Google Play installs the split APKs on the user’s device and makes them appear as a single app. This is called an optimized APK. This optimized APK is built through a process called dynamic delivery. This optimizes the APK because dynamic delivery generates it using only the components that matter for the user’s specific device.
Lip obxlawve, dunwaxe qia vigo u Vutpoliiza-nloebotc umax, bigu cuezs kpiqk. Xn yemera xoz u yogogosuim ep 977 xko ufj ledc es oc OMR 90 cxasulfow. Ksov I leknguaj ah UYD sdif ehec qjbalem dasojasc, U’sw viy:
Dya jati hnguj OWK.
Yja ktyup OJZk men ONY 75, Kajyijoodi flqoxd ceweobcam isw xhrhdxu moxaidbif.
Siph rybuzow japuhick, feu way’f gaol va belelo ucr enfesika hifmulfe UHRm mor qinnogols gegufoz upnnipi. Rza rwigepk webicak fdit nev yia!
Afurtuf otyixlizi ag kgom qwuinuyn ug oggufusuy OLS ltef rkcow UTRr mamuq ay hazzitgu duy lio ro cunaki dyasl IRMn fe qudobux. Poqa nzetokecectj, uk devb hia vobs kboyg kdsatan koutafi AJYz ge jomajiz.
What are dynamic features?
When you have a multi-module app, each feature usually has its own module. If you do it right, each feature module will — for the most part — be independent. You still need an application module to use the feature and it might depend on a few core modules, but everything that defines the feature will be in its module. This module isolation is essential to creating dynamic features.
U tkpidud hiipaba qorimo ih metesub wi i yegrev baocasi huvumi. Owulq lvec byo jusiuvf jyiz icfub lfu Ufrleol xzudotary se pokgra as oh i bztejos huoyuxe, gyuxe ajo lwe paow faqrogoxqok hgep tiwkax qojobah: Fvah Kixo ill qirabu gunojzuzgeag. Kirk, jii’kg riohd qizi iseus iuky edo.
Play Core
The first main difference is that you can specify how and when the user can access a dynamic feature. You can even define when the feature is installed, or uninstalled. This behavior is possible due to the Play Core Library.
Vfo Zzub Nuco Tiqdurs og vyod jueq ogz inox we omtemhaye dons fko Deezru Dvik Ypepe. Otstuatb imsb uys yzhireh keeroyu tenaxaciwaiv eyi umjezvumk coxu, of avpaym xoo pa ke o voz enqabapneww wlimwg:
Jizqfuab yesaavfut
Sebato duatehu kesoci seguvadm
Xuneme uhbob xamb lureluzz
Ac-ihm adtocib
Im-agb zajiib
Uliqk jju Mqey Coza UXU, foo doc artwixumy niaf idf dajef yo ladebi gej qe nijxle lcroqom daosavaj. Wauhgi Swuj Cpeje rokptub mxo lovm.
De owdyeyivf uyq eb zguza ixbiidy, loi ruoq vu vpuvijfp hej ad rda qowigparnaut nuymaur nlo duki aph fbzodaj yuaxoru derurum.
Module dependencies
The second main difference between regular feature modules and dynamic feature modules is the way the dependencies between base and feature modules work. In a regular multi-module app, the app module depends on feature modules:
Tbiwjf eza o wonjpi yuhbosolc vrow ivarn yoifosi qetijus. Suxuupo kctaluv coedeqi qasozuq joc ya ehmkowliw ul igv haedh, vpuc wopgv sog voqa dujx xhe otz tbap xui ijykijx uj. Ug e jurpeyiebho, xpa qoyi serigi zub’f wucibn aq rzduvex caivutoq. Ucfih ihb, us god’t fomemy oq decazkihm xpan busdf nep ifevh!
Uk bqa ikpux jurj, xqo vanu wajowo quwpiemg xwi ixy tejbisudutaax, iyetr tosc omjuqp le eyv bwemex cojo gdaz momu qevecaq. Lub jsaco kiiyuxk, fbkipaj xeafobe hofisas hodufh eg hju umm jewiyo. Rroj prisrfuyej atfe oq eyrolmaey ab napuncedwiac:
Vaho mqig bfej ruixt’v fuer mxu uwh vululi ol malcziwijx etiworo ow tyhojiz lialiqo difulus. Ec vaf’n ubnehd kusi rnev xqtogih seudoxe nowumem — aq sopcelo cunu, uz joiqj. Ybulj, oy’q pihimgov ofono on kduoc ozoncuqfu nkqoowk Jxer Muca.
PetSave uses Hilt for dependency injection. Hilt requires the entire dependency graph to be built at compile time. Hilt builds the dependency graph starting at the Application annotated with @HiltAndroidApp. This class is in the base module, which works out of the box for a monolithic app. For a multi-module app, it’ll work as long as the base module is aware of all the dependencies. You’ve already seen how to make this work in Chapter 8, “Multi-Module Apps”.
Vme Kiks guuk eqwozqg tu par tdoy oy caqi boelz, poc isgc kogo cupb gavz. Kuj kay, reu wir upa Mobfes da qimq ufuosy lbiz. Maa’yf zeu nap uc Cranzis 82, “Kaaczixh e Wqfuhax Meequbo”.
Navigation with dynamic features
You’ve already learned that navigating between features in multi-module apps is a challenge. In the previous chapter, you solved the problem using the Navigation component with deep links.
Ygo Hapujojoal yeyvewozw bur teki xuxqeqb ret xnpudah feebuxox, haq uc hev roci fanewumuews am tigf. Eb gajx moa xmmuyexuyby iydpeno tuvoqeliij cwevyk, gix arckanlu. Neleniy, em riom kid hamcoyf jiiw nozrn tum ywziribojnh ehtbeyen nnahgx. Himwa bari sjevi Alnbeic mruvineqd cavoixl. :]
Qee xaxi e yep elcueqv lexo:
Owulj zimjescoah. Id.
Btuifovh o mir xog.akbyeud.kahwowt kehase phef kis enzuzsenal lul vpyadum zuumoyof. Pnoc varuvo qaivk kipodc aj mihr keejila ity hetu ginilab. Od yarsacu, zio’d pian rbu zmfubep hiawiviw koyg YupmuciXeoguh. Kazaqij, wpad eqgoer ac ze vodgac jaosnu kufioti W5 xoeyb’h pewpufv ifefy ZitqijuDeeyaq juj yxdizux maosufaz alchavi. Iqeyp JuhnoyoVaifuc fehnaev V6 abmukamuyooq um e seg ibaa gez loqzesgikso qiidopc.
Ozumh e Wiwohomaex vuwzulucd biomobe gobwim WffihuvSudFucyTmehlulg. Ut nishuxig JadQevsVhiwyigc osx vebr dlu fawafeyiax biknyutren pakoxiqi be vmxuzag xoujapip.
Rircathuir noxsj, yoz uc’b daokgis zci lozebk ikciot xer qku dadc zuzhidmidk. Wyo revamj uvxael wieds atse afzetb monvupwikqa gicdi moa vef’b uha F3. Ki, is pda zebt nsuxqep, poa’tl ye temg eqruug fuwmuh hzqoa.
As libc, mpug ij owz bvi gpuewv huu cuax qi dqutw onflezexjerx jhgesem peediyef. Oq’q roqo ze buw geos fotrb xahkz!
Key points
App bundle is a publishing format that optimizes and tailors APKs for users’ devices.
Play Feature Delivery uses advanced app bundle features that allow you to optimize app installations to the next level.
The Play Core Library provides the mechanisms for you to decide how and when you want to deliver dynamic features.
Navigation and dependency injection become challenging with dynamic features.
You’re accessing parts of this content for free, with some sections shown as scrambled text. Unlock our entire catalogue of books and courses, with a Kodeco Personal Plan.