Navigating Your Way Around Customizable Delivery (Android Dev Summit ’19)

Navigating Your Way Around Customizable Delivery (Android Dev Summit ’19)


[MUSIC PLAYING] DOM ELLIOT: Hi, everyone. My name is Dom. I’m the PM for the app
bundle and dynamic delivery. I’m excited to be here. This is my first
Android Dev Summit. I’m going to be talking about
the Android App Bundle today, then I’m going to hand over
to Jason, Wojtek, and Ben who are going to talk
about modularizing apps with dynamic feature modules. Many of you who have
started down this path have given us similar feedback. You say you love the
features, but you want the testing and the
development to be easier. So I’m going to spend some time
on testing today, and tell you about some new features there. And if you’re someone who’s
given us that feedback, I think, hopefully, you’ll
like what we have to share. As a reminder, the app bundle
is the new publishing format which replaces the
traditional monolithic APK. The app bundle is not
installable directly. Instead, Play generates
optimized APKs for each device from the single
app bundle which you upload. These APKs are
typically much smaller than if you were to install
a single monolithic APK. And the developer experience
is much simpler too. It’s much simpler than managing
and versioning multiple APKs for every single release,
so it saves developers a lot of time for each release too. The momentum we’ve seen
has been incredible. Over 270,000 apps and
games are using app bundles in production. That represents over
25% of active installs. And app switching have
seen, on average, a 20% size saving versus a universal APK. And partners who have switched
have seen up to 11% increase in installs from
the size savings. And if that’s not
enough, the app bundle also enables modular app
development and custom delivery options. So you can add app
modules to your artifacts, and then you can control which
devices get these modules, and when. Now this is fully optional. You can just use the app
bundle publishing format without using these
advanced features. You can also modularize
your app without using any other customizable
delivery options. At Google, we’re big believers
in modular app development. For our teams, it speeds up
our engineering velocity. Our teams can independently
build, test, and debug features that they’re working
on instead of everyone working on the same big,
bloated complex code of a monolithic app. With customizable
delivery options, you have control over how
and when modules of your app are delivered so that you don’t
have to deliver everything at install time. Conditional delivery allows
you to deliver modules at install time based
on different conditions, such as user countries or device
properties– device features. On-demand delivery means you can
install and uninstall modules on the fly when
your app needs them. We’ve seen partners
build modules for a variety of use cases. For large features
which are only used by a small percentage
of their users in the app. For specific hardware,
or software capabilities, or Android versions, like
delivering an AR module to devices which support AR. And sometimes for
large libraries, like if your app has a card
scanning library which is only needed once for the lifetime
of the app, that can make sense in an on-demand module,
which you can remove later. Our vision goes beyond this. We’re working on a dynamic
framework with more options. So in-app updates allows
you to trigger updates from within your app so that the
user can download and install your app update without
ever leaving your app. We have a whole session this
afternoon on in-app updates, and we have some new
things to share there. We’re also working on
customizable asset delivery. So this enables the app
bundle to include asset packs. This is especially
useful for games who want to package large
game assets with their game binary in a single artifact. And then we’re
going to introduce a number of delivery options for
how you deliver those to users too. And we’re introducing new
features which complement this dynamic framework. So we launched a new app size
report in the Play Console. This gives you new size
data, like download size, and size on device. And it gives you size
guidance when you’re using the app bundle too. Recently, we added new metrics
relating to your users, and we show you the proportion
of your active users who have low device storage. So these users can
present an uninstall risk, and optimizing your
app size is one way to potentially reduce that risk
of these users on installing. We’ve also added a new feature
to Google Play’s app signing service as well. So this allows you to
upgrade your app signing key to a new cryptographically
stronger signing key for new installs. This is especially
useful if your apps been around a long time, and you
created your app signing key a long time ago, and it’s not
as cryptographically strong as you want it to be. And finally, there’s
internal app sharing. So this makes
testing app bundles and dynamic delivery
a lot easier. I’m going to spend
some more time on this, and we’re going to give you
a demo as well, because it’s a really, really useful tool. And we’ve been improving it
and our other testing tools based on your feedback. So internal app sharing
gives you a fast way to share your apps
for local testing with the full confidence that
what’s installed on the device is exactly what Play would
deliver to that device if your app was in the world. All you need to do is
upload a bundle to Play. Then you copy a sharable
URL, and you give that to one of your testers. They tap it and they install
the app on the device. Developers who are using
this say it speeds up their workflows dramatically. And note, you can make anyone
at your company an uploader to internal app sharing without
giving them any other access to the Play Console– that’s been really important. We want to show you
how easy it is to use, so we’re going to
give you a quick demo. Please, can we
switch to the demo? Wojtek is logged into
Chrome as the uploader. He’s going to choose a test
version of his app bundle artifact to upload. He can name it
anything he wants, and then once it’s
uploading, Play takes a few seconds
to process it. You can also automate uploading
to internal app sharing using the Play Developer API. When it’s ready, voice
is going to copy the URL. Now voice it’s going
to switch roles and he’s going to be the tester. So on the phone, you can see
here he’s received the link. All he needs to
do is tap the link and then he’s able
to install the app. Once he starts
installing, Play is delivering the
exact splits which are needed for that device. This is really useful. So whatever device you’re
using, you just tap that link and Play will give you
the appropriate links. Now before he opens the app– oh, he’s already opened app. [LAUGHING] We’ll go back. So when we go back to the link– if it’s possible–
you can actually see here the exact
splits which have been installed for this device. Now when he opens the app, we
have actually a dynamic feature in this app as well. So now he’s going to go ahead
and load the dynamic feature, which is a compose module. Play is going to deliver the
splits for this dynamic feature in the background and
install them for the app just like it would in the wild. And now when he goes back
to the list of splits, he can actually
see the splits now include the splits for
the dynamic feature. Cool. That’s the demo. This makes it easy to test
exactly what Play delivers. It generates from an
App Bundle which you upload to internal app sharing. Now you may be asking, what
about all the other artifacts you’ve uploaded to
the Play Console too? So we’re actually going
to add install links for all the artifacts you’ve
uploaded to the Play Console. So you can simply go
to the Play Console, grab an install link just
like internal app sharing, share it with the
tester, and they can install that on the fly. For app bundles, you can
go to the bundle explore and just switch to
any old version, and you’ll be able to
copy an install link. And there’s one
final testing feature I want to tell you about. This is something that a lot
of people have been asking for. We’ve added
FakeSplitInstallManager class to Play Core. So this allows you to test
an app with dynamic features offline. Normally, when you load an
on-demand dynamic feature in your app,
SplitInstallManager will request the Play Store
installs the splits for that dynamic feature. And you have to
wait– you’re online– you have to wait
for them to load. Using FakeSplitInstallManager,
your app will just install
the splits which are needed locally, offline. You don’t have to wait for
Play to deliver and install the splits. This makes it very easy to
iterate on dynamic features early on in the development
process without needing to be online, without
waiting for the Play Store. And then you can still
switch to SplitInstallManager and do full online testing
with internal app sharing when you’re ready. This is available now in the
latest Play Core release. So these testing
features I’ve shown you are all about making it
easier for you to test your app bundles and dynamic
delivery, for that testing to be part of your workflow. Please do keep
giving us feedback. We want to know what’s missing
and how these can be improved. With that, I’m going to
invite Jason up on the stage. Thanks. JASON LIU: Thanks, Dom. Hi, everyone. I’m Jason. I’m a product manager,
and I work on Google Play. Today, I wanted to talk
about feature and feature dependencies, which is
a feature many of you may have requested over
the past year or so. So let’s talk a little bit first
about dynamic feature modules, and a little bit
more in general. So here, you can see– let’s say you have
an app with three different dynamic features. One of them is green, one of
them is orange, and one of them is blue. Overall, the goal here
that we want you to do is modularize your
app, which is to break your app into these
different dynamic features so that basically, you have
better separation of code for all of them. And then the kind of end result
that you can get ideally here is that different users can get
different portions of your app. So let’s say you have
three different users– you have Android 1, Android
2, and Android 3. Android 1 may only
use the green feature, Android 2 may be a
bit more advanced and use the green
and orange feature, and Android 3 may use the
green and blue feature. Overall, the advantage of
this is that each of them can get whatever parts
of the app they need, and they’ll have a
much smaller app size than if they had download
the entire monolithic APK. We’ve seen and we’ve noticed
that for every three megabytes that a developer
decreases their app by, they may get up to 1%
increase in conversions. So this is a very,
very important thing that we want all
developers to invest in. There’s a couple
other advantages that you do get out of
modularizing your app. The first one is faster
incremental build times. For example, if
you only say I want to build the green feature
and the orange feature, you can build this
faster and spend less time building your app,
and more time developing it. Another advantage you can get
is more logical separation of code. So for example, if
part of your team wants to work on the blue
feature and part of the team wants to work on
the orange feature, there should be less
cross team dependencies if you’re doing this correctly. Let’s talk a little bit
about the three different– or four different, actually,
methods of delivery for dynamic features. So there are three in general. There’s one which is called
“at-install delivery,” one is called
“conditional delivery,” and one which is called
“on-demand delivery.” At-install delivery happens
when you actually install the app for the first time. So let’s say you
install your app, and then the dynamic
features automatically download onto the device. Conditional depends on
the actual configurations of the devices themselves. So let’s say that you have
a device that supports AR, so you could get a
conditional dynamic feature that actually goes to devices
only which support AR. The third one is
on-demand delivery, which says that, hey, I want
to download this feature right when the user requests it. The fourth type that we actually
have is instant delivery. And if you guys aren’t
using [INAUDIBLE] already, [INAUDIBLE] are a way
that users can try out a smaller version of
your app before they decide they actually
want to install the full version of your app. And on the Play Store, this
is represented by a “Try Now” button which is right to the
left of the “Install” button, so they’re right
next to each other. So the user can press Try Now. Try Now is a smaller
version of your app, which can be up to 10 megabytes,
and then install the full version of the app. Originally, when we announced
instant and dynamic features, we had a limitation that instant
dynamic features could only be used with at-install delivery. So if you wanted to use
on-demand dynamic features, they only could be used
in your installed app. Today, we’re announcing
that these delivery methods are completely separate. So you can use instant
dynamic features, or instant enable dynamic
features with all three of these different
delivery types. So you can use them
with at-install, you can use them
with conditional, and you also can use
them with on-demand. So we’re basically
just giving you the freedom to
not have to choose between one or the other. One of the caveats
of this is, let’s say that you take your instant
enabled dynamic features and mark them as at-install. If you do this when they
uses the [INAUDIBLE] and then installs the
full installed app, these features
will automatically be downloaded and
installed for you since they’re all marked as
at-install dynamic features. On the contrary, if you mark
some of them as on-demand and you use them in
your [INAUDIBLE],, you’ll have to prompt for
the user to actually download these on-demand features
inside the installed app because they won’t be
automatically downloaded when you first start
using the installed app. So the way the dynamic
features work right now is that they only can
depend on the base APK. And here, we represent
the base APK as colon app. And let’s imagine that
you have your app, and it has three different
dynamic features in it. One of them is a camera feature,
one of them is a video feature, and one of them is
a payments feature, and these can be all
completely separate. Let’s say, for example, that
you have some common code that is required by both the camera
feature and the video feature. And let’s say this is, for
example, some image processing software. The way this works right now
is that the image processing software is common to
both camera and video, but they only can have
dependencies on the base. They can’t have
dependencies on each other. So what happens is the
image processing software must live in the base APK, which
is represented by app here. The problem here is
that if a user only wants to use the
payments feature, they will essentially
download all this image processing software because
it’s part of the base APK. And the base APK is
what you download when the user
initially downloads your app from the Play Store. We’ve heard from the developers
that this is actually quite a big problem. It’s not possible to reduce
the size of your output very much because
you can’t really pull all the relevant
pieces out that you want to out of the base APK. Today, what we’re
announcing in Studio 4.0 is that dynamic
features can depend on other dynamic features. Here, let’s say that you
have the same example where you have image processing
software, which is used both in the
camera dynamic feature and the video dynamic feature. You could pull all this image
processing code into the camera dynamic feature. So if someone comes
to your app and says, hey, I only want to
use the payments part, it will not get this
part of your app, because it will only be in
the camera dynamic feature. So only users who use the
camera part and the video part will get this code. Overall, this should result
in much smaller download sizes for all of your users using
these dynamic features. So let’s talk about how to get
started– this process is not too difficult. We’ll start– overall, it
starts with getting the first version– our new version of our
Android Studio Canary which was released yesterday. And then we’ll talk through
how to get it from that stage all the way to uploading
to the Play Console and deliver it to users. So the first thing
that you’ll have to do after getting the
Android Studio Canary is that you’ll have to
add a specific, what we call a feature flag. You’ll go to Help, and
Edit Custom VM Options, and you’ll add this
line of code there. This will be removed
in a future canary. And don’t worry, this talk
will be recorded and posted, so you won’t have to do this. It’s also in the release notes
for our upcoming canary, which is out now. And you’ll just add
rundebug.feature.on.feature to this file, and save and
restart Android Studio. The second thing
after you do this and you restart your app is this
is what you’ll see in your run slash edit configurations menu. So here, let’s say that
your app still has the three different dynamic features. You have camera,
payment, and video. And what this
dialogue lets you do is it lets you try out
different configurations of dynamic features so
that you can make sure that your app works
well for users using any of these configurations. So here in this dialog, we have
camera, payment, and video. There’s two things
to note here– that if you select the
video feature at the bottom, you can see on there that the
camera feature is required by the video feature. So if you want to say,
I want to try out my app and test out the video
feature, it will automatically select the camera feature and
download this and install it just as it would be if a
user was downloading this for real from the Play Store. The second thing
that you can note is that if you deselect
the camera feature here, you will also select
the video feature just because, obviously, if you
don’t have the camera feature, you won’t be able to use the
video feature in your app. So you can try out all
different configurations just to make sure this will work
well on all user’s devices. A couple other steps that
you have to do– the next one is that you have to list
all the dynamic features you have in your base APK’s
build.gradle file. This is exactly the same
as you’re doing right now. If you have three
dynamic features, you’ll list camera,
video, and payments right in the app’s build.gradle file. The next thing that you’ll
do, which is the major change that you’ll have to
make, is you have to modify each of the
build.gradle files to make sure that they all
have the right dependencies on each other. So let’s say here, if you
look at the payment feature, it depends on the base
APK which we call “app.” If you look at the
camera dynamic feature, it also depends on app. But if you look at the video
feature here at the bottom, it depends on app and it
also depends on camera. So the only change
you have to make is you’ll have to add this
line, “implementation project camera,” which denotes that
the video feature does depend on the camera feature
to work successfully. And after you do
this, Android Studio will parse all of
the dependency tree, and it will show up in your Run
Edit Configurations menu, which was on the previous slide. So basically, modify
the build.gradle files, and then it
will show up in Studio and you’ll be able to
test this out, as it goes. The last part that
you’ll have to do is build your app normally and
upload it to the Play Console. Play will make sure that all of
these relevant dynamic feature modules are automatically
served correctly to your device. So if a user, for example,
requests the video feature, it will automatically download
and serve the camera feature here. And this will work for the
entire dependency graph of all the dynamic
features that you have. Thanks. This was feature and
feature dependencies. And I’d would like to
invite Ben onto the stage to talk a little bit more. BEN WEISS: So I
would like to talk to you a little bit about
navigating dynamic features. When it comes to
navigation, we have had a lot of different
options throughout the years. So let’s take you through
the framework APIs as well as a couple of existing
APIs that we have and libraries that
we have there, as well as showing you
things that we have in store that we’ve been
working on that we want to share with you today. Well, when you use
the traditional way– so you navigate using
framework APIs– you usually have two different
APIs that you can use. You either start an
activity using an intent– that’s the easiest way
to start a new screen for your application. And within that
activity, you can use the supportFragmentManager
to use fragment transaction to replace fragments as you need
them to be replaced to navigate from one screen to the other. To help you with
this, we introduced the navigation
architecture component. This makes it easier to
navigate your screens, and it’s a Jetpack
way to do navigation within your application. Within the navigation
architecture component, we released the
Navigation Editor. The Navigation Editor
allows you to do manipulate the destinations, and
then manipulate the navigation path that should be taken
for these navigations– for the destinations without
actually having to touch code. So you can click, and drag,
and drop the relations between those destinations
without actually having to write code. It all gets stored underneath
in a navigation graph xml file. So this is where all the
navigation destinations end up. And you can manipulate
them manually, but the Navigation Editor takes
care of most of that for you. Then there’s still a little bit
of code that you have to write. Within your layout
file, you have to reference the
NavHostFragment. You can set it as
your default fragment and reference the graph
ID that you just created, either manually or with
the Navigation Editor. Cool thing about this is
that after you change this, you don’t have to manually
start activities or interact with the fragment manager itself
anymore, because the navigation component takes care
of all of this for you. On the other hand,
we heard a little bit about dynamic feature modules
and on-demand delivery already today. With app bundles and these
dynamic feature modules, we dramatically changed
the way that apps can be installed
on users devices, as well as the way that you
navigate from a base model to an on-demand
dynamic feature module, as well as to a regular
dynamic feature module. Like we showed
earlier, an app can have multiple dynamic feature
modules, each of which can be installed at
install time or later on using one of the
customizable delivery options. This means a module
might not be installed in the first place when
you try and navigate to it. That caused some problems
with the navigation libraries, and it did not– because
[INAUDIBLE] expected a module to be there at the time
you try and navigate to it. So we decided to
take a closer look to what we can do
to make it easier for you to navigate to dynamic
feature modules that are not installed when you try
and navigate to those. So today, I’m excited
to share with you that we created a
new set of libraries called the “Dynamic
Feature Navigator.” It’s a new set of [INAUDIBLE]
libraries that builds on top of the dynamic feature– on the top of the
navigation component as well as on the other hand
on the Play Core library. The version I’m sharing today
with you is a development snapshot, so that means there
are likely changes to the APIs as well as to some
of the functionality, and some of the
UI that we provide before we go into a
stable version with this. But we worked to make the
transition from navigation to dynamic feature navigation
as smooth as possible. So let me show you
how you get started with an already
existing navigation graph, and an already
existing on-demand module. First thing you
have to do is you find your currently
existing NavHostFragment and replace it with the
DynamicNavHostFragment, which is the new class which provides
the base implementation, and the easiest way for you to
interact with dynamic feature navigator. Next, you have to make changes
to your navigation graph. Jason showed earlier
that you have to declare module names at some
point in the build.gradle files in order to tell your app
which modules are installed. You have to do the same thing
within the navigation graph here. So you basically just add a
module name for each feature– for the destination of each
feature where it is in. So the dynamic feature navigator
knows where to look at– which module to look
at in order to install the feature as it’s needed. After making these
changes to just two files, you can navigate
from a base model, download and install
a new module, and launch it as required. All this without touching
any further code, and it takes care of handling
the installation state process, and all the states in
between there for you. At this point, you might
wonder how does this work? [LAUGHING] So let me show you how it works. Generally, when you use the
navigation component, what happens is navigate gets
called, and navigate and the navigator knows how to
navigate from one destination to another. When you’re using
dynamic feature modules and they’re not installed,
the navigation component does not know how
to come from A to B. So what we used within the
dynamic feature navigator is we enable navigating
to these destinations by providing an intermediate
progress destination. This progress destination checks
whether a module is installed or not, and if the
module is installed, directly and transparently
navigates to the destination. If it’s not installed,
it takes care of downloading and
installing the feature, and then launching to the
final destination for you straight away. We are aware that a great
out of the box experience is not everything, and
developers want also to be able to customize
their experience to fit with their
existing app, and to be paired with your existing
UI and user experience. So this is why we
provide an API for you to extend on all the features
that we have in here. While the default
progress fragment gives you safe, out
of the box experience, you can customize it. And the easiest
way to do this is by extending the
AbstractProgressFragment. You can pass it in a layout
ID that you can use in order to show what you want to show. And then we have a
onProgress function which transparently calls down
to the Play Core API for this so you can display
the progress as it is happening to your users. We also provide
functions for you to override for several
[INAUDIBLE] states that you might want to handle. To set the customer onProgress
fragment that you then created, you open up your nav graph
and add the fragment’s ID as a progressFragment. And at some point within the
navigation graph hierarchy that you have, you also have
to set the progress fragment with that fragment ID in order
for the navigation component to catch it. If you don’t want
to go down this road and want to create your
own UI, but you still want to know what
you can monitor and where the state
is currently– which state your installation
process currently is going on, what we introduced for
that is a class called the “DynamicInstallMonitor.” So you might want to just show
an installation like this. Instead of opening a
completely new screen, you might want to
show a little pop up that just has exactly
a feature, but it still shows your download
process and all this. We created the
DynamicInstallMonitor to enable just this,
and experiences as you like them to do– as you would like
to create them. So you can check with
the DynamicInstallMonitor whether the installation is
required in the first place. So if this returns
false, you’re all good to go– you don’t
have to show anything. You also can subscribe to the
status of the installation, which gives you back
a live data with all this SplitInstallSessionStates
that might be available at this point– at any given point in time. And you can also check whether
the installation is in an end state, which is one of the
states where the installation has failed, canceled, or
you cannot go on from this. So the installation
is very unlikely– absolutely impossible
to go on from there. To use it, you create
the InstallMonitor, pass it to the DynamicExtras. And these DynamicExtras
then get passed into the navigate function,
where you can then subscribe afterwards
to the live data and observe the split
states as they appear. Next to that, the libraries
are fully customizable. So all the APIs that
I showed you today all are built on a core
library underneath. So we did provide the AndroidX
navigation-dynamic-features-core which provides all the APIs
that we built ourselves the APIs on top of that for activity
navigation with dynamic features as well as fragmented
navigation with dynamic features. We recommend you to start
off with the fragment version of it, because that
gives you the easiest way to interact with dynamic
feature navigator at this point. If you’re interested
in drilling down, you can go all the
way down to the core and build your absolutely
custom experience. If you do, and if you
interested in this, please come and speak with us. It is a snapshot
version, and we’re very interested in
hearing what you’re up to and why the things
that you’re doing might be able to benefit
other developers as well. So we’re very interested in
hearing all your feedback. You can use the library
today as I said earlier. So the snapshot
version we provide is accessible within
this snapshot repository. No worries– you don’t
need to take photos. We’ll share this in the
video description, and then social media later on. And then you add the snapshot
version to your dependencies, and you’re good
to go and use it. There’s a couple of things
that are coming soon. So like I said, in
the snapshot version, not everything is there
yet, not everything is– well, the things that we
currently have are working, but there are some things that
are not working at this moment. The Navigation Editor
does not support the way that the dynamic feature
modules graphs can be displayed, so we currently do
not support this. So we’re working on that
which is coming soon. As well as deep linking into
nested and included graphs. Also the SafeArgs plugin does
not work with dynamic feature modules, because it cannot
cross module boundaries easily. When you find a bug,
please go and file it. Let us know what’s going on,
let us know what’s going wrong. If your feature
requests, also go there. Thank you very much for this. And with that, let me
hand over to voice. [APPLAUSE] WOJTEK KALICINSKI: Thanks, Ben. So we’ve seen how the
dynamic feature navigator can simplify launching into a UI
hosted in a dynamic feature module. But we also know
that not everyone is using the
navigation component, and also not every
dynamic feature will even have a UI, like
a fragment on activity. That’s why following on
our announcements earlier this year, that we are
committed to making the Kotlin experience on Android
the best in class, we are announcing today
a new Kotlin extensions library for Play Core. So the goals that we had
when we created this library are similar to the
other KTX libraries that we have, for
example in AndroidX. Because it is an
extension library, it doesn’t replace the
main Play Core artifact, but builds on top of it. It uses the same
APIs underneath. That said, building on
top of the existing API, we took the opportunity
to simplify it and to help guide developers
through the correct flows and the recommended patterns
of usage of the API. And we are doing that by
leveraging the power of Kotlin Corourtines. So let me show you what I mean. So this is the
original Play Core API, and it’s an async API–
it’s asynchronous. Most methods on the
SplitInstallManager return immediately with a task. Now use the task to
set callbacks on it. The addOnSuccessListener
lets you listen for the work to be completed, and you can do
some stuff after it completes. And then you, of course, need
to add the failure listener where you can get exceptions
and handle any failures. So how can we do better? So this is how it
looks in Play core KTX. It’s the same call, but it
has a couple of differences. So let’s talk through them. First of all, you can notice
there are no ugly callbacks. This call is sequential– it
returns a result with a session ID instead of passing that
through the task and callbacks. That’s because this function is
actually a suspending function, so it has to run in a coroutine. It’s suspending but
it’s not blocking, so it’s safe to call
from the main thread. And it will return result– you can assign it to a value. This is implemented as
an extension function on the SplitInstallManager. So like I said, it builds
on top of the existing APIs. And on top of that,
we of course tried to use all the Kotlin syntactic
sugar whenever it makes sense. Like in this
example, we’re using default and named
arguments, so it’s easier to call these methods. Now this is all
great for functions that return a single
result. You can use the suspending function–
it returns the result, you can have it in a coroutine. But the Play Core API is much
more complicated than that. This is the example of an
install process for a split. It goes through many steps. It emits many status
events along the way, and a simple suspending
coroutine function is not something that
would work for that. Normally, in Play Core,
you would handle it with a listener. Now this is not
the first and not the last listener based
API that you’ll see, but what what’s
common for all of them is all this boilerplate
code you need to run. You need to register the
listener at the right time, you need to subclass a listener
and provide your own status handling. And then the most
important part– you need to clean up
at the right moment whenever the listener
or the object leaves the scope to prevent
memory leaks and lifecycle issues. So can we do better? Let me introduce
you to an API called “Flow” that’s also part of
the Kotlin coroutines library. In this example,
we’re requesting a flow that will be
emitting status events about the installation
that’s happening for splits from the Play Core API. Now the collect
function on the Flow is also spanning, which means
this will run in a coroutine. And there’s one more
property of coroutines that I haven’t mentioned today
that is really important, and that is that they
support cancellation. So in AndroidX, we– in the KTX libraries
for AndroidX, we give you extensions
on the view models, activities, and
fragments that give you scopes for running
your coroutines as long as the screen is active. So as long as if your view
model is active, or a fragment, or an activity, you will
keep getting events. As soon as the user navigates
away from that screen and the scope gets canceled,
we also cancel the Flow, clean up any listeners,
and you will not get any more events after
your lifecycle is finished. So that’s great. And on top of that, Flow and
the Kotlin coroutine library comes with a lot of
operators built in, so you can deal with the streams
of events in a really nice way. Like here, for example, I’m
filtering the stream of events only for the updates about
the module I’m interested in. So this is a much nicer way
of working with this API. And speaking of
progress events, let’s take a look at the
listener once more. So I told you that the
installation process is quite complicated– it goes
through many different states. How do you know, as a developer,
which ones are important, which ones you need a
handle for the installation to be able to continue, and
which ones simply maybe affect the UI, but are not essential
for the installation to complete? It’s really difficult.
Some of them you need to handle,
some of them, not. So we’re providing a
convenience function that creates the listener
for you, that takes lambdas. And for the mandatory states
that you need to handle, such as handling
user confirmation for downloading
a big module, you need to provide these arguments. And of course, all
the other states are optional arguments, so
you can handle them as well and show it in your UI. So this is available now as part
of the new Play Core release. You can get it now
from our gmaven, and we’re excited for you
to try it out and give us your feedback. And please check out the in-app
update session later today, where you will see more
examples of using Play Core KTX for in-app updates. So thanks, everyone, for coming
to our session and watching online. We really hope you enjoy
the improvements we’ve been making to the way you can
test your dynamic features, the way– how managing your
dependencies work, as well as the libraries that
we’re releasing to make working with our APIs easier. So please try them out, and
come to the sandbox, talk to us, let us know what you think. Thank you very much. [MUSIC PLAYING] [APPLAUSE]

3 thoughts on “Navigating Your Way Around Customizable Delivery (Android Dev Summit ’19)

Leave a Reply

Leave a Reply

Your email address will not be published. Required fields are marked *

Copyright © 2019 Geted Tabs Online. All rights reserved.