Android Dev Summit 2021. October 27, 2021. Android Dev Summit 2021. Android Dev Summit 2021. Android Dev Summit 2021. Android Dev Summit 2021. October 27, 2021. Android Dev Summit 2021. Android Dev Summit 2021. October 27, 2021. Android Dev Summit 2021. October 27, 2021. October 27, 2021. Android Dev Summit 2021. Android Dev Summit 2021. Android Dev Summit 2021 October 27, 2021. Android Dev Summit 2021. October 27, 2021. Android Dev Summit 2021. Android Dev Summit 2021 Android Dev Summit 2021. October 27, 2021. October 27, 2021. Android Dev Summit 2021. Android Dev Summit 2021. October 27, 2021. Android Dev Summit 2021. October 27, 2021. October 27, 2021. Android Dev Summit 2021. Android Dev Summit 2021. October 27, 2021. Android Dev Summit 2021 October 27, 2021. October 27, 2021. Android Dev Summit 2021 Android Dev Summit 2021. October 27, 2021. kick-off this year's Android Dev Summit 2021! To start off, we have another episode of the Android show with me, your host. This year's summit is about building excellent apps across devices and coming up in today's keynote you'll get a peak into the world of team Android, our very own Android avengers! And the tools they're building to help developers to restore order and stability to apps across the Android-verse speaking of which, I have created a superhero alter ego of my own! From now on you can refer to me as captain curiosity, traveling down YouTube rabbit holes at the speed of -- why? Houston, we may have a population error. Team jet pack, can I get a little help over here! Team jet pack! Let's do this!. That's more like it. Yeah! Get em! We built the bug together! I helped! That was wild! Heck yeah! They let me keep the laser glove! All right! Coming up, we'll hear about how to build excellent apps using the latest tools in modern Android development like Compose as well as the latest news on updates to help you extend your app across devices to new form factors. First, kicking off this keynote, you will hear about some updates on where the Android team is heading this year, and it all starts right now! Right here! From our fortress of code-atude! You're my hero!. My God! It's cold!. Hmmmm. Better!. >> Sagar Kamdar: Thank you for joining us at the Android Dev Summit 2021. I hope your loved ones are staying safe and we look forward to when we get to meet again in person. I wanted to give a special hello to our communities and women tech maker ambassadors that are championing Android and joining us from around the world. While the last year and a half has brought many challenges, one of the bright spots has been seeing the way developers like you responded, the app experiences you have built to help people around the world in ways we couldn't have imagined. Let's look at some apps created by Android developers in our community. Starting with an Android GDE from Argentina. He created a food delivery app that enables users to get food delivered to their loved ones all over Argentina. Joe from the U.K. built an accessible guitar to help the mute, deaf and blind to learn how to play the guitar with a combination of a built in speaker screen and a braille reader. Another, an Indian healthcare start-up, which provides personalized care to patients with chronic illnesses. These three are great examples of focusing on the use, understanding their needs, building experiences to delight them. This spirit is what drives us at Google and our work on Android. At the end of the day, our goal is to build a platform that we and all of you love to use every day, and one that billions of people around the world will also love. We're very excited about the advancements made this year on Android, with Android 12 we have taken a user first design approach centered around you. Smartphones are deeply personal, and Android 12 helps the entire phone adapt to you with material you design language. It is the biggest design change in Android's history where we have rethought the entire experience from the colors, to the shape, to the light and motion. The result is a more expressive dynamic, personal experience than ever before. We'll share some news on how you as developers can use this in just a bit. Android 12 also focuses on security by default. That's part of a much larger investment across Android and Play in the security safety and trust space. With this release we introduced Android's private compute core, an opensource secure environment that's isolated from the rest of the operating system and apps powering critical features such as smart reply, live caption, and we'll continue to increase our investment in Google play protect, scanning over 100 billion apps a day for potential risks. We have continued to give users control and transparency when installing and using an application. Our next step will be the launch of a new data safety in Google Play that informs a user of what data is collected and why before they install an app, all of us have a critical responsibility to our users to maintain trust. When they're happy, we all succeed. Another big theme for us on Android is helping all of your devices work better together. Based on all of your feedback we have recognized there is more we can do to help experiences that extend beyond the phone to an entire ecosystem of devices including where abdominals, TV, cars. I'll share just a few examples of our efforts from the last few months. Today one out of three smartphone users have a fitness tracker or smart watch, recognizing that we have taken our collaboration with Samsung and mobile to the next level and launched an entirely new version of wear os and brought richer, immersive app experiences to wear os with Google play, YouTube music, Google pay, spotfy, and much, much more. On TV, we have just launched one of our most requested features to date, your Android phone has remote control features built in that can now be used for any of your Google TV or Android TV devices. We have also made major improvements to Android auto for you to stay on track drug drive, including support for more app categories like navigation, charging and parking. Finally, over the past 18 months we have seen people around the world buy and use Android tablets, Chrome devices and foldables more than ever before. In fact, there are more than 250 million active large screen Android devices. Last year Chrome OS grew 92%, five times the rate of the PC market, making Chrome OS the fastest growing desktop OS. With schools being online, individuals working from home, having a large screen device that's easier to use for extended periods of time is essential. We would like to thank all of you who have invested in making your apps work great on large screens and we have also heard your feedback that you want to us go bigger on Android with large screens. I have already said, Android 12 is one of the biggest releases in history. Today I'm excited to announce we're going even bigger, we're adding additional support for large screens in Android 12, Diana will be joining in a bit to share more details on this news. With that, I want to kick it over to my team who will focus on two big themes today, first, excellent apps and updates to our modern Android development offering to help you stay more productive so you can focus on building great applications. Second, helping you extend the apps across devices, as users want to experience the apps you all have built on all of the form factors that they use on a daily basis. Once again, thank you so much for joining us today for building amazing experiences ininspiring us to make Android better every single day. >> My name is Moyinolwa and I'm a software engineer and an Android GED, I started maps and learned programming fundamentals there and my career was not complete until I saw apps that my friends built and I wanted to learn how to do that. Being an Android GDE means that I have a platform to contribute to the Android developer community. Modern Android development, the three things I use the most are compose and others, and this was out in 2017, months before it was aknowned as the official language for Android development. I remember that I was very excited about that announcement, that I gave a talk introducing all of the developers to this. I love this, it is a let less verbose and I love that the checks are built in and it is more fun to work with. One of my favorite features of Android studio is the inspector, I like it because sometimes I need to make changes to another portion of the code based on a place my team doesn't own, because of the size, it is difficult to know sometimes the classes that you need to change. I can easily get an idea from one of the elements and that reduces the amount of time I need to search. I have been using this on my personal projects because it reduces the amount of time required to create a new project and we no longer have to have separate files. And in compose I'm excited about the column feature which has replaced the recycler view and ADS21icly reduced the complexity required to work with dynamic teams. Sometimes at Twitter, we're using compose in production and I am excited for more teams to start using it too. >> I'm Florina, when it comes to building excellent apps, many best ideas on the Android team come from talking directly with you, our community of developers. Understanding how you work, how we can make our tools and services even better so you can be more productive and focus on expressing your ideas. We call it our expand and collection of development tools, APIs, language, distribution technologies and modern Android development and it is the combination of ten years of building Android developer tools and best practices. It is powerful for fast, easy development, enabling you to create better app, there is ones across billions of devices, modern development starts with great programming language support, officially supporting Kotlin is an example of a investment coming from listening to the community, you love it, we love, it I love it. Today of the top 1,000 apps, 87% contain Kotlin codes and even more 40% use Coroutines. New this year, we have our life cycle aware APIs that are now stable and repeating on life cycle and flow with life cycle to stop collecting from the UI when not needed. We're not stopping here, we're working on expanding the guidance on Kotlin, flow, app architecture. The processing, our replacement for the annotation processing tool, it is now stable. KSP offers similar functionality with faster compilation time and direct access to Kotlin language constructs. Room for 2,000 times improvement time when switching and we're working on moving others. The latest life cycles are being built from Kotlin and the most exciting, it is the Android new normal UI toolkit to build better apps faster. This is stable and ready for news production and we will be able to work with the current apps and it is exciting to watch the adoption of this. We have seen thousands of apps on the play store using compose. It is incredible to see the reaction after working with compose, they're telling us how easily they create beautiful apps quickly. How simple it is to ad features like animations. The experience with square, it is how I felt with compose, they told us sometimes it is almost so simple you expect it to be more complicated. Things just work. We're working to expand compose support overall factors, starting with home screen wings and more on Compose and wear OS later. This goes better with a range of component features and tooling. And we continue to expand the APIs with features like the animations, search over scroll for Android 12, improving target sizing and more. We have add had faster refresh for live edits and so the changes show up on the device and the preview. We have added compose support to studios in the layout adding compose specific for the inspecting the tree. We're not done yet, we have so many features planned. The public roadmap, check it out to see what's coming next. Now we want to show you how this looks in action. Over to nick for a demo. >> Nick: Thank you. Here is an app we have worked on to create our own yet pack heroes. This is made with jet pack so it is fast and easy to build, but don't take my word for it. Let me show you how. For example, I have been seeing a list of the hero friends and all of the Android dev super powers, we can iterate on an individualist item using Android studio preview. Here I have previews of the friend item allowing us to see it in light and dark themes and with a larger font. You can display near realtime updates of literal values, I can change padding values, the image size, seeing them update immediately. This works both on the device and in the preview. This produces a fast iteration cycle keeping me productive. When I'm happy with an individualist item compose makes it so easy to display that list of items. To build on this, we can use the clause column composable to call the friends composable in an items block. That's it. No more layout, adaptor, viewers to manage. One of the absolute favorite things on compose is how much easier animations are to write. I want the items in the list to animate in. I can simply wrap the list in an animated visibility composable which will animate the entire list entrance. I can also use the animated and enter and exit modifier on individual items and here let's add a staggered animation. I can switch my list to use items index to give me the index of each item. Then in the modify, user index to customize the slide in and entrance animation. Like this, each item will enter from further out and come together. Let's take a look in the experimental animation inspector. We can play back and scroll through the entire transition. Pretty nice. Compose also uses spring based animations by default. It is easy to configure the animation with a slight bounce by reducing the damping. Hopefully this shows how marvelous compose is for making you feel super productive. Over to Andre. >> Material U, it is a radical new design vision focused on delivering experiences that are personal for every style, accessible for every need and adapt active for every screen. Starting today, with justice pack compose, realizing this vision is even easier. In Android 12 the material you experience is front and center. From the spirited shapes of the new widgets, to the expressive use of motion and large type on the home screen, the updated visual design is fresh, alive, original. The days of one-size-fits-all are long gone, people are eager to express their individuality and seeking more personalized experiences in every day life. For me, the most exciting thing about moving to a new home is going to the paint store and finding that color that will best represent my style and make me smile when I unlock the door. When I get a new phone, the first thing I do is set my wallpaper. So do about 60% of Android users. I typically choose some abstract art for a photo of my dog, something personal. Building a dynamic color pallet from a device wallpaper, the material you create is a tailored experience that's reflective of the user's personality and applies it thoughtfully throughout their Android device experience. To get a feel for apps that support dynamic color, let's take a look at how we have applied it to the updated Google apps. The G mail, calendar, calculator apps are great examples of how we can maintain the recognizability of the apps and keep them feeling unique. We have updated the styling, improved the accessibility of our navigation components with new state indicators and color mappings, so your apps are optimized to reach more people on more devices. Now that you have seen what apps with dynamic color feel like, let's talk about how to make them. Today we're releasing a new version of our material components libraries for Android use and preet view of the material use support and jet pack compose which will help you quickly and easily create amazing, personalized app experiences. All of the updated components, design guideline, developer documentation can be found on the new material design 3 site at material.io. We understand this is a new way of thinking of color, in order to support your team, we're releasing material theme builder, a new tool to visualize dynamic color in your app designs. With its built in code export, it is easy to migrate to the new color system and take advantage of the dynamic color, the material theme builder is available as a web tool and a plug in which you can use today. All of these great material new features are available on pixel devices with Android 12 and we're excited to roll it out to more devices in the Android ecosystem soon. Back to nick to see this in action. >> Nick: Material design and compose, two of my absolute favorite things, teaming up to make it fast and easy to build beautiful material apps. I have just a friend to help us update the app. Let's get an assist from my designer. >> Hey, nick. I saw the material design logo in the sky and came as fast as I could. I have been playing around with the material theme builder and seen how dynamic color may look within the app. I didn't know there was so much color in the whole galaxy. Applying dynamic color is going to give our app the extra boost it needs. First, we need to migrate our material design three to take advantage of the beautiful colors. Let's create a custom theme. We can use the primary container color to highlight primary actions like this which is now over 50% more fabulous and use container color to heighten attention to an element, such as the power boosts. This is looking great. With its built in code export nick can implement the new material 3 theme and ensure dynamic color maps beautifully across the UI. Nick, are you ready to implement this? >> Nick: Yes. After adding the material dependency to the app we can update the theme composable to work with dynamic color. We use dynamic color when running on Android 12 and updating the theme logic to use the dynamic dark or light color scheme functions to retrieve a color scheme extracted from the devices wallpaper. That's it! That's all I have to do to update my theme to use dynamic colors. The updated material components use these colors so depending on the device's wallpaper, then the app is completely different feel to go with it. In the material videos, I noticed the fun slider, this is not part of the material free library, this is composed, let's build it. I can move the sliding component and the rendering logic to draw a wiggly path rather than a frontline. Compose make it is easy to animate this. Let's alter the path using remember transition to add a wiggle and we see this right here in studio with the interactive preview. Material U made the app more personal and more fun. Back to you. >> to my personal favorite, jet pack. We have been working to add the features you have been asking us for. Navigation brings multiple support, no code updating, just making sure you use the latest version. WorkManager, recommended solution for persistent work makes it easier to handle background restrictions adding support for expedited jobs and room, auto migration and multimap relations. All right. Now if I have the mic, I'll go deeper into the migrations. The most common database operations can be handled out of the box like adding columns, tables, primary keys. All you have to do is add the auto migration definition. For some changes like renaming the column, table, you have to lend and have the authorization. You have four lines of code, not just one. I can talk about room all day, bullets tell you what's in store for two of our newer libraries, they are data store, our core team replacement for shared preferences reached a preference storage to store the key value pairs or the type objects, you use the flow to store the data consistently and transactionally. Now that the data store reached 1.2, start using it in production. Macro benchmark, it improves frame form man's and simplies and compatibility. Finally, because we know that understanding your apps performance, it is important, we added support for profilable AKIs in Android studio to measure timing more accurately. Without the performance degradation of other apps. So from material U, compose, the latest jet pack libraries, that's a lot of modern development features to help you be productive building excellent apps for your users. Now, back to you. >> Thank you! Wow! All those updates to compose the Android mean more apps that are in fact excellent!. So while team compose was showing off the new bug blaster, I have been busy building a gadget of my own! Check out the Kerry9,000! Time for a beta test!. Still working out the bugs! Anyway, we'll check back with nick and Yasmine in a bit. Let's chat about how Android is helping developers build excellent apps across any devicesor device, including large screens and foldables. First, our friends at spotfy will share with us how they used Android to optimize the apps for wearable, large screens and more. Looks like we need a bigger power supply. Wait, I have a laser glove!. >> Recent decades, technology has made music more and more accessible. It feels so strange to hold this in your hand like this, so retro. With the technology advances we have been seeing, we're moving closer to the mission. We want our users to be able to listen wherever they are, whatever they're doing. >> That's why with Google we have developed a seamless experience across screen sizes and devices. We have a design paradigm that we call adoptive UI modeled after the Google material design. This allows us to build for any shape and size of screen so users have a completely uninterrupted listening experience. A great example is Spotify with Android auto, to build Spotify for the car, we have had to balance the rich listening experience against our user safety. >> the ability for the user to ask the assistant to play anything they want is truly unique. Combining with the best in Class understanding of what the user likes to listen to, it makes the experience truly special. >> We pride ourselves on knowing your musical taste better than you do. >> You're big with it, it is an important principle for Spotify making sure user's audio is available in every moment of their life. Be. >> Wherever you are listening, you tie the Spotify ecosystem together. >> Technology changed over the decades, and that's made music and audio more accessible than ever. >> We're finding a new level of creativity for people to be able to express themselves in ways that we couldn't have imagined a few decades ago and that's an exciting place to be. >> a user digital life includes multiple connected devices and they expect all apps to transition seamlessly between them. Like we saw with Spotify, truly exceptional app experiences are no longer about developing for a single device but across devices building for the entire Android ecosystem. We are making it easier than ever to extend your app across form factors with some big announcements to unfold today. First let's talk about how Android is thriving across auto, TV, wearables and more. Android auto is now available in over 100 million cars and is supported by nearly every major carman fracturer. Our newest in car experience, Android automotive OS is available on cars from top brands including Ford, general motor, Volvo, most recently announced, Honda. To support this ecosystem we introduced the Android for car app library which allows developers of navigation, charging, parking apps to bring the capabilities to Android for cars. We're also excited about the growth for the Android TVos which now has more than 80 million monthly active devices globally. As mentioned, to help phones work better together with TVs we have built remote control features for Android TV apps directly into Android phones and through the Google TV app. It is a great time to integrate your media apps with the Android TVOS. And when it comes to wearables, at IO, we announced the launch of the new wear OS and it is the platform's most anticipated release ever. The new wear OS powered by Samsung has since launched on the galaxy watch 4 series with great success. Many developers have created helpful experiences for the latest version of wear OS and we're looking forward to richer, more immersive app experiences like what we're seeing from Spotify and others and they're seeing higher engagement with the apps. Now on wear OS, tiles are enabled for devices like the galaxy watch 4 providing predictable access on information and actions. Take this example from calm, giving users more entry points to access their app, the API is in beta for you to try out now. You asked for more modern Android development and we're now making it easier than ever to develop on Android's smallest screen, compose makes building UIs so much faster and easier. We're bringing composed support to wear OS, you can design your app with familiar UI components adapted for the watch. After several releases, we're now in a full developer preview with new samples and documentation to help you get started. Try it out and give us your feedback before we finalize the APIs during beta. Even more modern Android, we have also been working on new jet pack APIs and capabilities like the support for curve text and new health services. With these are a set of Column first APIs rewritten from the ground up. They're going to beta so that the time to migrate to them, it is now. In partnership with Samsung, there is a new watch face studio which enables you to create watch spaces in an editor, so watch you see is watch you get! Lastly, we're making it even easier for people to discover and wear the apps when opening Google play. We have added a new watch face search filter, and category pages allowing people to browse specifically for watch faces. We'll also be introducing wear OS specific ratings and reviews to give users a better impression of the experience on a watch. Finally, we're making the best ever investment on the large screen, foldable, tablets, chrome OS, we're incredibly excited about the innovation happening on foldables, they're redefining mobile devices with new models from Samsung, Microsoft and others. We have seen more than a 2.5 increase in device sales this year and it is easy to see why. Foldables put the power of a tablet right in your pocket. Speaking of tablets, usage in the home and at work transformed in recent years with an almost 20% increase in tablet sales that's continued throughout 2021. Users are doing more than ever on tablets, spending almost 10% more time than they did in 2019. Chrome OS grew 92% year-over-year, making it the fastest growing desktop OS in the world with over 250 million active large screen devices it is so important to ensure your app works across any size screen in any orientation. Large screen UIs present an opportunity to extend your existing phone app so that user requests see and do more. This is important for our own apps, such as Google photos. We updated the Google photos app to work well on large screens and saw an improvement in daily active users by 53% for key features. It is time to breakaway from designing for a 16 by 9 portrait phone app and start building UI responsibly. To help with that, we're releasing new features to make it easier for you to support large screens. Adopting and compose is a perfect opportunity to make your UI fully adaptive. All UIs described in code and it is easy to make decisions at run time about how the UI should look. No more relines on resource qualifiers. We are releasing material navigation component support and implementations of large screen lay droughts help you understand how modern UI development should scale across screen sizes. We have heard from you that knowing what screen sizes to develop and design for is hard. Our new window size classes are an opinionated set of break points telling what you sizes are the most common from phone to foldable, tablet, desktop, you will see these size classes across the design guidance and and as API and jet pack manager 1.1, you will see new reference devices in Android studio making it easier for you to develop against all combinations of window size classes. There are many more updates from support for new features like rear camera selfies and jet pack, to adding testing in studio. Let's see how it all works in practice. To see how it looks on larger screens, I'll go to the resizable immolator making it easier to look at different display sizes without juggling multiple immolators. Looking at the app on foldable, tablet, we have not taken advantage of the extra space. Can we update the designs to be more responsive? >> Yazmine: There is adaptive design patterns that will work. Let's switch the bottom navigation to make it for larger scales and we can use the list detail view pattern on the front screen to show more at once. >> Nick: This is combined with jet pack window manager makes it easier to look at the window size class or the folded state and I can then update the UI in response. For example, I have a top level scaffold to switch between showing navigation bar and narrow screens and the navigation rail on wider screens. We can check the window size class and arrange things with rows or Columns accordingly and we can show the friends list and a friends detail composable side by side in the expanded site. We can animate the change, animating the weight given to each pane. This will encourage you to create reusable UI easy to rearrange or combine and at run time using control flow. It is easier for an individual composable to respond to the space they're given like this screen which is from a list to a grid of sliders on the wider screens. I have an idea for how we can take advantage of foldable screens here. We can observe the folded state and in tabletop mode reposition the UI to work best in this posture, check it out, yes. Looks great. Moving our interactive components to the bottom of the screen ensures we make changes without toggling over the device on the tabletop. I can't stop folding and unfolding this. Now back over to you to expand on large screens. >> Diana: When developers adapted the apps to fill the entire screen and be fully resizable we have seen users use more time in the app. Zoom has taken advantage of tabletop mode on foldables for hands free video calls, they're working to optimize the UI fully for split screen usage and larger layouts. With all of the work that developers are doing for large screens, you need an OS to match. We're going big! Today we're releasing a developer preview of an upcoming feature drop for Android 12 with updates added just for large screens. We call it 12L. We have been working with developers like you to understand what APIs you need and upstreaming changes from device makers that users love. 12L includes an API with a redesign of the OS for large screens, added multitasking support and updated compatibility modes to make the app work better on large screens out of the box. Let's take a closer look. We have redesigned Android's UI from the ground up for large screens. Scaling the UI to work with any screen size including larger tablets and optimize home screen layout, updated lock screen and a two-column notification shade is some examples of transitioning from a folded exterior screen to a larger interior screen on a foldable. Users say they love multitasking on larger displays from using split screen to doing more in apps and we know getting into split screen is not super discoverable today. So we have added a new task bar to make multitasking easier than ever. Now you can use the task bar to switch quickly between apps, drag and drop to enter split screen and swipe up to go back to home. We have also added more ways to enter split screen from the overview and in addition we're helping users by automatically enabling all apps to enter split screen or multiwindow mode regardless of whether they're resizable. Even if you have yet to invest in optimizing for large screens we have updated app compatibility modes on Android and chrome OS. We have improved the user experience and better respect the devices orientation, letter boxing apps that don't support resizing or both portrait and landscape. With all of these changes, you should expect to see an increase in split screen usage and your app in windows of various sizes, it is important to make sure that your app adapts to this seamlessly. We're also making it simpler for apps to take advantage of the extra screen space, even if your existing application architecture still relies on multiple activities, with activity embedding coming in 12L and jet pack window manager 1.1 you will be able to display multiple activities side by side so you don't have to rearchitect your app to support list detail or other multipane app layout. We're committed to make it easier to support the large screen layout through the platform and jet pack. We have put so many features into the Android 12L feature drop, we encourage you to check it out in our developer preview dropping today on the emulator. For foldable, you will see many of the features, including activity embedding, coming soon to the Samsung galaxy fold 3. On tablets, you will soon be able to load the developer preview on the Lenova pro, take a look as we gear up for public release in 2022, this is a huge step forward in our support for foldables and tablets and will incorporate more features for large screens into our regular releases moving forward. To make it easier for people to find the best app experiences, we have got new changes in play to recommend apps optimized for the large screen. This includes new checks to assess app quality so we can feature large screen optimized apps and update search rankings to show the best possible apps for the devices. We'll also be introducing large screen specific app ratings so users rate how your app works on the large screen. This is coming in the spring and we're giving advance notice to get the apps ready now. Okay. There is so much for large screens. Let's do a quick recap! Available now, a bunch of developer APIs and tools to help you optimize your app for the 250 million large screen devices we have today. We're also dropping the developer preview of 12L, features on the emulator, you can download it now to explore how your app will look with the up coming up dates. Soon, you will be able to test out the features on real devices like the Lenovo12 pro and the fold 3. Finally, 12L and play store updates will begin to ship to consumers in 2022, get ready for the next wave of foldable and tablet devices. We're excited about this as the future of the Android ecosystem. The best part of this, it is that so much of this applies to devices available right now, expand how you're thinking about extending your app to the larger screen, try the new APIs and tools and check out the 12L features to help you bring the app to foldables and tablets today. That's all we have got time for today on the Android Show! We have covered a lot! From material U now available in Compose, Android 12, a brand-new developer preview of Android for large screens and foldables! Want to learn more! You can read more at developer.android.com. So the Android Show is winding down. But the Android developer summit is just getting started! We have just dropped over 30 technical sessions of Android developer content so you can dig in at your own pace, over the next two days you have a lot coming at you! Including your opportunity to get your #ask Android questions answered live with the experts that build Android. Thanks for tuning in to the Android Show!. Now, if you'll excuse me, take that!. studio team.from the Android >> I'm Jamal. Also from the Android studio team. >> Tor: Today we'll walk through what's new in the Android developer tool space. I'll be giving a demo a little later on, but first Jamal will cover what's been workeled on recently. >> Jamal: Today we'll cover three main areas, recent changes in Android studio, an in depth demo and a quick recap to talk about what you have heard today. On to recent changes. First off, Android studio is currently in the stable release channel. At Google IO earlier this year we spoke quite a bit about all the features and in case you forgot, this major release has three major focus areas. First off, design. This was the first stable release that included tool support for jet pack compose and a host of design tools and inspectors to make it easier for you to create and preview UI. Secondly, it had a sizable amount of features focused on Android devices from a heart rate sensor on wear OS to an updated Android emulator that supports Google TV. Lastly, but not least, there was a ton of effort on improving developer productivity with under the hood improvements and even tools for WorkManager. Let's take a look at the material you can download today in the beta release channel. In this release, you will find the initial support of material you and more refinement in the jet pack composed tools. Next we spent time on creating features that make you more productive. Lastly, with the bumblebee release you can get started on scaling your app for large screens with Android 12L. To see some of the features in action, now Tor will walk you through what's new. >> TR: We're about to stabilize the bumblebee release, the next is code named chipmunk and I'll show that here today. The first thing, we'll upgrade this project to chipmunk. We have the AGP upgrade assistant to help with that. That's short for the Android grade plug in. We'll begin that upgrade. We can show usages and this will show us what it is about to change in the project. I can accept the suggestions. Run the import and now my project should be upgraded to use the latest version of AGP. Next, we will build the project and once we do that, we can open up the build analyzer and look at suggestions and one of them is to look at the build configuration time. If you click on optimize this, try configuration cache in a build, the studio will run through the build with configuration on, checking whether the build is compatible with configuration Caching and in case it is, we can enable that and now the builds will be faster setting this environment right here. One thing we plan to add to the build analyzer soon, it is also checking whether the jet fire is necessary, for now it is just turning -- you can turn off yourself, if the build work, that makes for a faster build. Another related feature is support from R classes. For that I'll switch to a larger project, this is the canine mail app. What I can do, I go to the refactoring menu and choose migrate to non-transformative R classes. This will analyze the whole process, look at the source files referencing resources and it will rewrite them to the project local and turn on a setting in the build system system which will make builds be able to skip a bunch of resource emerging and this helps with performance and definitely recommend switching to this if you have a project with lots of mo Dulles and resources. Now, the LOST thing I will say about build speed is for light A top request from the users is making linked faster on your CI servers. So in bumblebee, Canary13, later, we have the incremental casts and the remote Caching, let's show you what that mean, this is the about 30 mo Dulles with 100 lines of code around 1100 source files. Here, because we have caching on, and because I have not made any changes to the project, if I clean the project we can see that there are no linked reports here. If I run it again, with caching on, it pulse in the reports in a matter -- pulls in the reports in a platter of a few seconds -- in a matter of a few seconds. If I make a f change to the file Let's do that. Here we will change this path so it is an SD card path, a new check, this is a new incident, so now I run clean, and this again so, we simulate the CI build here. Now you see that again it's pulling in a lot of results, only analyzing this one module that changed, and so compared to the three and a half minutes this would take with older versions, now we get an updated report in 17 seconds for this project that we can look at. While we're on the topic of performance, let's look at the profilers. A feature that we are putting the final touches on now, support for helping to you track down a UI that's not keeping up with the frame rate. So here is the trace that I have already recorded, and we can switch to the frames view and with Android 11 and 12 we can now capture the frame life cycle so these are the frames in the capture, and I'm going to sort them from the duration of the time spent in the application. So it looks like frame 1748 was pretty slow. So when I select it, you can see the frame life cycle on the left. It is color coded so the purple bar here, it is in the application, the same purple bar over where it is waiting for the GPU and composition and in fact if we zoom out a little bit, we can see when it is spending time on the display. As you can see, the previous frame was on the display for a while. That's our jenk. Now, of course, the next step, it is to look at the application and render threads and we can swipe out the selection here. Now you can go, look to see what it is, the application was that it was doing, to figure out what the sources of the Jenk and in this recording, we were trying to load the textures at the same time, it cost the jenk. Let's switch gears from performance to our graphical editors. This is the camera app with the view finder right here and we have some labels of the picture below it. What we want is to have the UI rotate in place as the camera moves between landscape and portrait. We have made that very simple with motion layout. We have two states, normal state for portrait, the landscape orientation, you see what's rotating the controls. If you look at the XML for this, all we have to do is set the constraint routed attributes in the motion layout and in the manifest, locked to the portrait manifestation. So let's see what that looks like. We'll display the transition here. You can see that we're animating, rotating the icon up here and the label. So let's look at this on a real device. As you see, we have embedded this into studio, it starts from the snapshots in just a few seconds, we spent the year stabilizing and tuning it and as of bumblebee, this is the default. Notice when the camera is active, studio knows that and gives a hint on how to navigate the virtual theme. I can now hold the shift key and move the camera around to the virtual seam that the immolator is presenting to the camera. The embedded emulator also has access to the full extended controls for the emulator now. We can, for example, set a route for the navigation or we can access the virtual sensors, and for example, we can change the device post which is exactly what we want to do here to test the rotation. If I start rotating the device sideways, you can see that the UI here is updating to rotate with the sensors. This is still fiddley, let's run it on a real device. Another feature, it is the device manager, we have removed our AVD dialogue and we have integrated the devices here and you see the virtual devices for the emulator and the physical devices that I have attached through Wisc wi-fi pairing, ls run this on a real device. As you see here, when I rotate the phone, it is smoothly animating between the rotation states. All I have to do was set attributes in the motion layout. We're exploring a feature to make it easier to test this within the design surface without running on a real device. We have seen how to play the animation in the design servers like this, well, I can also go ahead, rotate the screen in place in the design surface like this so we can actually test the animation right here while editing it. Let's take a look at a different layout. Here we have a welcome screen where we're animating in a welcome message to the center and we start off off screen and animate in. The top priorities for Android 12L, it is handling the large screens and different form factors and one of the concepts was device classes so you see that we have the various reference devices listed in the device picker. So let's switch to a tablet mode, you can see that here we start out with a welcome -- the welcome message not in fact off screen. This animation is broken for large screens. Now I found out by actually looking at the various different screen sizes. We don't really want to force you to do that. We have this new feature that we're working on called tentatively visual linked in. So if I open up the problem view here, you can see that we're actually saying that we have a button which is partially hidden in layout. We're basically looking at different preview configurations and seeing if a view is on screen in one and it better be on screen in another as well. Let's open the layout validation view. Here we can see this layout across all of the screen sizes and again if I open up, the problem view, we are now showing you the inconsistency right here between the two layouts. This is not just about checking specifically for things being out of bounds. Here I'm looking at a realistic app, this is a task tracker and if I bring up the issues panel here you can see that it is listing a number of issues that it has found. Again, let's open up the validation view and let's look at the messages here. For example, it tells us that we have this view and consistency we have already seen, it knows that it only wants to see the bottom bars and narrow layouts and here it is really in wide layout where is you have the text lines longer than 120 characters which is not grit for usability. The key thing here, I didn't have to go in and audit all of the configurations on my own. Studio is checking these things in the background and we plan to expand the things we're checking beyond screen size issues, for example, we can look to see if we have unexpected wrapping in certain locals, so on. Last but not least, let's talk about compose. We shipped full support for compose in Arctic Fox and in bumblebee we added several new features. So first there is interactive preview. So if I go and click on this icon here, the touch icon next to one of the preview, we start interactive mode and this starts usually in under 2 seconds. The key thing, now I can basically test -- touch handling in my app so we're sort of running the app in the design surface and I can for example click to open up the shopping cart. I can click to open up the menu, so on. It let's me do very lighting weight testing of the app and it is quick to start and exit. In a related feature to this, the support for animation inspection. If I click on the animation inspection icon next to the surface I now get this view of all of the animation curves in my animation and I can scrub through the different animations or I can play them on a loop if I so choose and this is a pretty handy way to go through and look to see how your animations are putting to in case you want to adjust some of the curves. By the way, in these build, we have the little icons next to the preview annotations, the configuration picker, which makes it super easy to go and change and configure the various previews for the composables. Now we know that an important aspect of compose is being able to iterate on the UI, changing the code and seeing the affects immediately. We know that build speed is a big hinderance today. We're working on a couple of features to help with that, the first one is live editing of literal, strings, numbers, bullions, so let's look at this sample app, this is the rally financial app. If I jump to the alert dialogue here, I can go ahead, change the text. Hello there. Notice how as I'm typing the preview is keeping up pretty much on the fly. This works for strings. It also works for numbers. I can, for example, change the padding to something, you know, much bigger if I want. Which I don't. And know that this is not just for the preview. Now I'm running the app in the emulator and this will work on a physical device as well so I can go ahead and change. I can go ahead, change the text, just like before. And you change the text like before and I can also change the numbers, I can change the bullion, for example we can switch the soft wrap to false which is clearly wrong, but you can also change it back. So far what I have shown you here are features in Arctic Fox, bumblebee, or in development 4 chipmunk, now I'll give you a sneak peak on some features we're working on for releases after that. The first one is live editing, and it is a generalization of the feature that I just showed you, live editing of literals, we let you edit the more general scenarios than the constants and strengths. Let's take a look. Here in the preview, for example, we go in, add a check box, and within a couple of seconds I should see the check box show up in the UI. Then I can for example add a loop around it. Now we're going to put in four checked boxes in the un and so on. We know having this side by side is super useful and we're making live editing work with that as well. Here is another app, we're playing with blur in Android 12. By the way, just want to show you quickly, we support blur in the layout preview as well in our rendering implementation for the design preview. Here is our running compose app. I can now go in here and not just change the strings as before, but I can for example comment out, parts of the UI, and I can reorder it, and this is basically the equivalent to me typing in new things, I can change parameters, so on. You can see basically this implementation works within mill seconds of the edits. It is a promising feature but, you know, we learn the hard way with instant run this has to be rock solid before we ship it. We're going to take time and make sure it is really right before we include it in studio. It is exciting. The next feature is basically the polar opposite of what I just showed you. That's light mode. So with live editing, we're on the fly as you are typing, doing lots of computations to show you the UI as fast as we can and with visual linked in we're running analysis in the background to find potential challenges in different screen sizes. This let's you say hey, I want you to use fewer resources as I'm using the Idaho ID. This is not int mode. As I'm typing, you can see that it is keeping up to date. Now, if I enter light mode, and this is built on top of intelligence power save mode you see that we now basically do not keep the UI up to date. In fact, if I were to open up another file, you can see this is an XML file, we don't default to show the split as normally do, just showing the source file n is another file and in light mode, as you see, it is not doing all of the normal expensive editor validation that it normally does. You still can use go-to declaration, and basic editing features like that. It is not running on the fly, validation, which of course uses a lot of resources. A key thing about this, so, you know, if I write something that's non-sense, usually this creates symbols, it doesn't do that. the key thing we have don't, it is that if I save the file, we temporarily unblock light mode so that you get the basic validation that you need. Crucially, you are staying in light mode. So the idea here is that we're tuning all of the features in studio to do less work when suitable when you're in light mode. For example, the layout editor will be doing cheaper image scaling and anti aliusing, so on, and we're disabling the editor feature like power save mode does. Again, this is an early exploration area and it looks promising. Hopefully something will come of it. There are, of course, many other features I wish I had time to show, the new features that are part of the intelligent 2021.2 merge that we have landed in chip among, there is the resizable immolators for 12L and much more. Now I'll turn back over to gentleman mall and using Android studio. >> On top of the tools that support phone and large screens, we have a full suite of tools ranging from tem plates, inspections, updated immolators and more for all of the Android device categories. To recap, the bumblebee release of Android studio has a range of features focused on jet pack impose, developer productivity and large screen development. We also give you a sneak peak at some of the features we're working on for the upcoming chip monk release. Download the latest updates to Android's studio today to get started. Thank you for joining Tor and myself. We look forward to all of the great app experiences that you will build with Android studio. session on WorkManager. I'm Ben, an engineer on the Android developer relations team. I'm joined by Rahul, a lead engineer, and in this session we'll focus on APIs and tools that we haven't talked about before in depth. You will also learn how WorkManager supports you to get back to the foreground so that your app can get work done even when they put it in the background. First we'll look at how and when to use WorkManager in general. From the stable release, WorkManager provided several foundational APIs, and WorkManager wants you to define work, put it in the queue, run it, let you know when it is done. Originally work could only be ran at a later point in time. With this kind of the full execution you are able to off load many tasks that can run at a later time. WorkManager respects the devices and the apps standby bucket. You won't have to think about when something needs to run, just leave that WorkManager, and because let's be clear, in most cases, it does not matter if you have the sync happening exactly at midnight. To make this more powerful, you can constrain when the work should run. Ic see when the December is idle, charging, has access to a active connection n allows you to handoff the checking for the conditions for WorkManager. You can focus on developing other features as well. With WorkManager you can make work dependent on other work. Once the data has been synchronized you can work this for clearing up the local log files or populating a base with new information. You can request work to be done in sequence or in parallel for seamless continuation of work. WorkManager will take care that all of the right conditions are met. Then run the next workers for you. This is something that should happen regularly. The WorkManager only supports one time work and also work that should run periodically, to make this fully transparent, you can check the status that your work is in. With this, you can see whether your work is queued, running, locked, finished. This foundational API is available since the first stable release WorkManager. When we first talk about WorkManager an and droid desk summit we of it as a library for magic the background work and on a foundational level that remains true. Since the foundationings were laid, several new features were added and the APIs modernized, you request work to be ran immediately while the app is in the foreground and it will continue to run, even if your app is put in the background. Now you can apply filters to a photo, save it locally, upload it, all while the users are doing something different, publishers of large applications have the needs to optimize the resources even further. WorkManager is well situated to take on the heavy lifting. With the new work multiprocess library, WorkManager introduced A picks and improvements to help to schedule and run work in a dedicated process more efficiently. We're aware of how important it is to test before shipping it to users. That's why we added APIs to enable single workers and entire work continuations, also in parallel to library release, support was improved. As developers, you now have access to detailed logs as well as inspections inside and outside of the sued yo. The new capabilities led us to rethink when to use WorkManager. While the foundational idea is still technically correct, it is a bit outdated. Today WorkManager can do far more than that. WorkManager can now take care of any kind of work you throw at it, so WorkManager really is solutioned for all work that you want to complete. Today we think of WorkManager as the recommended solution for persistent work. This is what we mean by persistent work. When you think of scopes, WorkManager runs the workers in a global scope. This means that the work will be around while the app is running, surviving orientation changes and other activity tear downs. That alone is not enough for persistent work. WorkManager uses the room database library under the hood to ensure that your work survives, processes and reboots. No matter the circumstances, you will always be able to recover the work status and have the possibility to continue where you left off. Work scheduled with WorkManager will be ready to go when it is your apps turn. That's what we mean with the persistent work. Now over for a tour on the work changes. >> >> You want to make it easier to run long running work, this means work that runs longer than the 10-minute execution window that work usually gets. To make it possible, WorkManager bind the life cycle to that of the foreground service. Job scheduling air the end processer scheduler are aware of the work. For all intents and purpose, the foreground service owns the executional life cycle, this added APS hub for that. Users have a limited attention span so WorkManager provides the APIs to make stopping long running work from the notification yourself easy. We are looking for examples in more detail. Here is an example of the long running work. You have a class downward worker extending and that's defining the working methods in the worker that makes things easier. Let's define the notification which knows how to build the Android notification with the provided information. Next let's define a method that is chunked downloads. This method takes the input and the source for the download and output file for the destination and the suspending call back which is called once per chunk of progress. The progress information in the call back is used to build the notification based on the previous helper. Now we can look at the full run for instance that WorkManager needs for the long running work. This is a combination of a notification ID and the notification instance. Here is where we put everything together, we have a suspending duel work method and we have the download method defined earlier with the input and the output file and every call back information is getting progress information. You use this information to build the notification and call the foreground to show this to the user. This is what makes the worker long running. After the download is done, all of the work has to be done successfully, and at this point, WorkManager looks at the execution of the foregrouped service automatically, cleans up the notifications and stops the service if necessary. The worker does not have to do anything to manage the service itself. Some banks users change their mind and want to cancel work. The running foreground service notification can easily be swiped away. We'll talk about how WorkManager make it is easier to stop the worker from a notification action. Let's look at our notification helper from before. The goal here is to add a notification action that provides the signal to WorkManager to stop the worker. That's what the user wants. The first step is to create a pending intent making it easy to cancel the worker. Using ID here to get the workforce ready and then we call the create cancel pending intent API. The intent provides can cancellation signal to WorkManager when dispatched. Now we need to build the notification with the custom action. Using notification compact builder to set the title and then some text. You then call add action which cancels button and the notification with the intent that we created earlier. Then the user clicks on the action and the pending intent is drafted to the foreground service executing the worker. The service then handles the intent and stops the worker. This means that an app cannot stop a foreground service when in the background, starting Android 12, setting foreground can result in a exception. WorkManager will help you with this transition. It actually is so important to us that you get this right that we recently released WorkManager 2.7 with support for expedited work. Expedited work is important to the user. The user initiated. This work can be launched when the application is not in the foreground. A good example of the work that needs to be expedited is a chat app where the app wants to download an attachment for the message or an app that wants to handle the payment or subscription flow. Expedited work is backed by a ground service on the API version prior to Android 12, this is where they're backed by this, expedited work is subject to quotas and while the application is in the foreground, the expedited work is not subject to any quotas or restrictions. The quotas apply when the application is in the background. The execution quota is based on the app bucket and process importance. Expedited workers work, it stops as soon as possible, it means it is latency sensitive, awon't support the delays and it is not for long running work subject to quotas, when the user wants to send a message that's important, it should happen as soon as possible with all of the other guarantees. Let's see how to implement that. Here we have a send message worker, extending, the worker is responsible for syncing messages from the back end for a chat app. Expedited work runs in the context of the foreground service, similar to long running work, prior to Android 12. The worker therefore needs to implement the get foreground info to show a notification. On Android 12, WorkManager won't show any additional notifications because the work is backed by an expedited job. Implementing the work, expedited jobs could be interrupted so the worker should keep track of some Saturday so it resumes when it is eventually rescheduled. To schedule the expedited work, you look at the expedited API and the WorkManager that this work requests is important from the perspective of the user. Because the work has been scheduled to subject to quota, you need to tell what you say to do if the app rans out of quota. You can become a regular work request, no longer expedited, the second option is to drop the request altogether, if it can be expedited. This means that no work is scheduled if the app is running on expedited quota. WorkManager starting 2.5, several improving.S for applications with the multiple process, let's explore those APIs and the motivation for them. The use of multiprocessing APIs, you have to find the dependency on the work. The goals of the multiprocessing APIs are a wide redundant, a work measure, secondary processes, you want to reduce light contention that happens with the multiple processes with the locks on the underlying database. You want to ensure that the in process scheduler runs in the process, and to understand which parts are redundant, you need to understand what's done when initialized. The first thing that happens, once the application is launched, its that the platform called application on create. At some point in the process life cycle, WorkManager instances are called and it kicks off WorkManagers initial routines, when WorkManagers initial lied, we run the full stop, this is important because this is where WorkManager checks if the app was previously stopped and ensures that the jobs a should have been scheduled are actually scheduled comparing what WorkManager knows, and where the job scheduler or job manager know, it reschedules, uninterrupted work, as you an tell, this is expensive. Comparing and looking at the multiple sub systems and the only ones that we have. The other important thing for you to note, the in process scheduler runs in the default process. Let's look what happens when the app has a second process. When you have a second process, we essentially repeat what happened in the first process. This process initializes as before, and given that this is a designated primary process, the scheduler runs in this process. For the second process, you have essentially the first process, application, creating invoked again, which in turn reinitializes the WorkManager at some point n means that we repeat all of the work we did in the first process, you may be wondering why we run full stop roundable in the second process at all. WorkManager doesn't know which of the processes is important. If the app is a keyboard, a widgets, then primary process may not be the same as the default process. The secondary processes don't get to run the end process scheduler, this is not the default process. The process scheduler runs, it is important, and it significantly improves through put giving it is naughtiest dealering limits that others have. For example, job schedulers has 100 john roberts and other DOS not suffer from the limits. Let's look how to find the designated fault process. For this, this is the app package name. When the application defaults the application process, it runs in that process. One of the secondary processes though, was there a way to be aware of the WorkManager in the secondary process. Turns out there is. What we want here, it was to not initialize the WorkManager at all. To make that possible we introduced the remote WorkManager, the class binds to the designated process and forwards all of the requests made to the designated process, using a service, this also means that the you avoid all contention altogether. There is only one process, designated process with the underlying database. In the second process you can create work requests like you did before. You have the WorkManager, here we have the remote WorkManager instead. This binds to the designated process using the service and forwards the request by parceling the request over to the designated process. The way this work, we manifest to the remote manager service to the applications and to the XML, this is service that is forwarded to the request. We look at how WorkManager allows you to define the designated process. That's still not enough. You may want to run a worker in a different process. An example of when you may want to do something like this is an ML pipeline, running in the secondary process for an app that has a dedicated UI process. You may want to isolate this work to a secondary process, it does not take the rest of the app down, especially parts responsible for the UI. To run the worker in a different process, you should extend remote worker, analogous to this worker. And when you extent the remote worker, you have to implement remote work. This method is executed in the secondary process. You have to define the process that the worker needs to bind to. You do that by adding an entry to the application and Android manifestation and the app defines one or more remote worker services, each in a unique process. Here you can see we're adding a new service called background. Now that you define the service in the Android XML, you have to specify the component name we want to bind in the work request. A component name is a combination of a package name, plus the class name, you are adding to the work request in put data. We then create the work request with the input data so that WorkManager knows what service to bind to. The end works like we always do, and WorkManager computes the work, it first binds the service based on what was defined in the input data and executes the remote work, all of the heavy lifting for a cross process communication is handled here. Now let's talk about tooling improvements and the app inspector in Android studio. >> Earlier I mentioned improved tooling support, now it is time to see that in action. Starting with Android studio Arctic Fox, you can expect the work directly in Android studio using the background task inspecteder. The background task inspecteder is part of the inspection suite which gives you detailed insight into several aspects of the apps. To get the most information the app must use WorkManager 2.5. The fastest way to open app inspection for the first time is to hit the shift key twice. This opens a dialogue that enables searching everything from code, other action, menus. Here you type app inspection, hit enter. This will bring up the app inspection panel. Alternatively you find app inspection in the menu under view, tool window, app inspection. Now that you know how to enable it, let me switch to a demo and show you how to use it. >> I'm using Android studio I have selected no filters and clicked apply. Let's slow this down for a moment. While this filtering process is ongoing, we see the status moving through the life cycle. Since these are workers that run in sequence, the Cleanup worker needs to finish before the next one can begin. All other workers are currently either in queue or blocked. Now that the Cleanup worker is done, the other workers along the continuation can do their work. I can also see the whole continuation in one picture. To do so, I select the single worker and then switch to the graph view by clicking on this icon. The graph view is essential for more complex continuations. From both views I can click directly on any worker and get detailed insights. At the top we have a basic description, including a clickable class, a unique ID. I mention the WorkManager persists the work data, let me show you how using the database inspector, clicking on the database inspector tab. Here I look for the unique ID in the table or I see that the information, it is on this particular execution, it has been persistent. Let's continue in the background task inspector. I can also see exactly which line this particular execution was not queued. That's super convenient, especially when comparing it with searching for calls manually. I can also see if there has been any constraints or particular worker as more detailed information object frequency and execution status. WorkManager can use the output data of one of the workers and pass it into another worker down the pipeline. You can see this in the results. The output data includes a unique identifier for each worker and its past along the work continuation. Everything completed as expected this time. I would like to show you what happens if a worker along the chain had failed. To do this, I inserted a failure worker to the work continuation and restarted the application. As you can see, the results from previous runs are still here for me to independent. Again, that's what we mean by keeping work persistent. I already selected another image and now I enable filters and apply them. After selecting any worker, I click on the graph and you can quickly see where the work started to fail. Thanks to the exclamation point rather than the Checkmark. From there I can directly click to the worker and continuing the debugging session. This failure is expected so I stopped the demo here. This concludes our session on WorkManager. You now now that WorkManager is the recommended solution for persistent work. You can request and council the long running tasks, you have learned when and how to use the expedited work APIs and now how it enables you to write solid performance apps, on top of that, you have learned how to use the background task inspector, and we have even more resources available for you to learn more about WorkManager. Early this year, we released an in depth video series of WorkManager taking you from over threading, advanced configuration of testing, and we got to answer many of the questions in the live Q&A session. We published multiple code levels to give you guided hands on experience with WorkManager. Of course, you can find documentation as well as code samples, all of the links are in the description. Let us know what you think in the comments and if you would like to see more content like this, give as you thumbs up. Thanks for watching. to the first ask Android, I'm Rebeca Franks and we'll answer questions on architecture, Kotlin, performance and there is a separate jet pack compose and material you ask Android session to ask deeper questions related to the specific topics. Feel free to pop the questions in the chat and you try to answer as many as possible. Before we get to that, a quick round of intros from everybody that we have in the panel today. >> I work in the Android jet pack team. >> Hey, I'm part of the Android developer relations team. >> AMANDA ALEXANDER: I'm a product manager on Android. >> WOJTEK KALICINSKI: Hello, I'm evacuees, I'm an engineer on the developer relations team. >> REBECA FRANKS: Great. Thank you so much, everyone. Just a quick reminder, pop the questions in the live chat and we'll get to them as soon as we can. We have a couple that are coming in from before the show, we'll dive straight into asking some of them. The first one, if somebody is very interested in Android development and has no idea about jet pack components, jet pack in general, what's the advice for them. A great question, this is something that the team has thought about, has provided and created resources forgetting started. The purpose of jetpack it to help developers have a suite of libraries to help you accelerate the development, follow best practice, reduce and write code that works consistently across different Android versions and devices. The components work, they can be adopted individually or they can work together. If you go to the an vo void.developer.com/jetpack, there is a lot of information there. There is a getting started walk through page that walks you through the various different articles, code lab, online training, that really walks you through overall how to approach either adopting jetpack in your existing app or creating a new app with jetpack. There is lots of examples and so there is a lot of great resources there and if there is any feedback that anyone has on additional things that can help people ramp up, really diving into the material, we're definitely happy to get that feedback. >> WOJTEK KALICINSKI: If anyone is a complete beginner, we have training courses that are made specifically to walk you through getting started with programming and they also teach the best practices with jetpack, so if you search for Android basics in Kotlin for example, you can get started and from there you can go and explore the different jetpack libraries as well. >> REBECA FRANKS: Awesome. Okay. Next question, what is the best way to collect flows from the Android I? >> I think I can take this question. The best way, the safest one, it is just to use the repeat life cycles, and to collect from the flow inside of the body of the function. You can use the flow with life cycle, flow operator, and that's going to be practically the same thing. API,ood thing about the they collect from the flow when ever they do this visible on the screen, that's something that alternatives do not do. Just use the APIs. Yeah. >> REBECA FRANKS: Awesome. Okay. I have some performance problems in my app, where do I go to start debugging with these kinds of issues and what tools should I use? >> AMANDA ALEXANDER: We have a few different jetpack libraries that target optimizing performance. So there is a Mack row benchmark library that measure as start-up and scrolling, or Jank frank per firm man's and we have a benchmark library measuring CPU, cost of specific functions, and so these library, they can be useder remotely to track metrics in a continues integration forum or you can also do them locally and profiling results are viewable within Android studio. In terms of tooling, there is also within studio, there are various different profiler tools you had to use to measure different metrics you're looking at for performance and we know that performance, it is a very difficult thing even if you get the metrics, you know that you're seeing the data, figuring out how to troubleshoot, really optimize it, there is guidance we have provided as well online to help you walk through some specific examples, just to kind of give additional guidance and additional hints as to where you can start diving deeper in the data that's output from your benchmark data. >> Yes. There was a performance series, it was a month ago, I highly recommend everybody to check out that YouTube channel where we have four, five videos on performance there. There was a great session with the team and it was very helpful. >> REBECA FRANKS: Great. So when is the next Android studio coming out? >> WOJTEK KALICINSKI: I guess I can take this one. So we don't normally give it, any date that we give, you know, releases slip and then it wouldn't be fair to give everyone this expectation that release is on a certain date. You know, if you follow Android studios tracks, release candidates, you can more or less figure out when the next stable release will be. It is basically when we're confident through release candidates that any major bugs are found and fixed, we don't want to -- don't want people to encounter major encounters at launch, the thing I can ask everybody to do is test out the beta versions, the prerelease versions and to let us know if you find anything that's not working. >> REBECA FRANKS: Great. So for new apps, features, should I learn motion layout or compose? >> YIGIT BOYAR: A difficult question. I will give it a try. Learning motion lab or compose is not -- they are -- they -- they have different systems. Ideally, you should go with compose especially for a new app, there is not much reason to try to write an application with old systems unless you have some historical code base. We have constrained layout working in compose already. I don't know the plans for motion layout, I assume it will probably come, the compose API, they're so beautiful, you can do a lot of that stuff yourself with compose, easier than you are able to do with the other, and in the worst case scenario, you want to use motion layout, you can embed the regular views in the compose regulations and they're interoperable and you can do that with compose, that's the feature. >> REBECA FRANKS: Great. That was a bit of a burning question I think. All right. Now there is one that's super popular, everyone wants to know the answer to this one, what is preferred, MVVM or MVI? >> MANUEL VICENTE VIVO: Yeah. I can take this one. In fact, the reason -- there is not much difference between the two approaches, the MVVM and the MVI, the model, the view intent, both of them are doing the directional dataflow, it is the preferred way to architect the applications. I mean, the one you choose depends on the needs of the application, it depends if you want to have the intents with the MVI and having everything reactive or not. It depends on the app, but I mean, no matter which one you use, you are set up for success, those are good patterns, they follow UDF as mentioned before. >> REBECA FRANKS: Great. Okay. Best way to communicate from update of data from repo to a view model? >> MANUEL VICENTE VIVO: A one shot call, if you have to stream the data, you have that recommendation. >> YIGIT BOYAR: Something to add there, normally when you try to design these problems, thinking about how can I notify that view model, it will kind of get you in trouble. The view model has a smaller life cycle than regularly. The way to think about this, it is mostly view model is not interested in some information from this, it will observe something, it will collect something, whether you're using -- that small difference, it give as perspective of whether you're trying to change something in the view model, something happens, versus thinking about the view model observing some data because you're interested in the information, and it will help you avoid a lot of problems down the line. So thinking about whatever has a smaller life cycle that observes the one that has a larger life cycle, another kind of thing with the visuals, try to look at the problems from that perspective and it will be a lot more straightforward for every single case you face, if it is between the view model or the viewed model and the views. >> REBECA FRANKS: A lot of great data. >> YIGIT BOYAR: It is fine. Live data, it is -- it is very purposeful class that we built for UI to hold the state for your UI, and you try to use the live data, it just doesn't scale and we don't want to scale it because it is always better reactive libraries and the purpose, it is simple to solve a specific case so only use it if you need to, especially if you're using the Kotlin and flow, you almost have no reason to use live data but you can if it is easier. Trying to use live data in the rest of the application, it is just not going to scale well. >> MANUEL VICENTE VIVO: Yes, reconsider the architecture and all of that. Historically, the data, it was integrated with the data mobile, and for example, right now, it is supported by data and we have these new life cycle APIs and, yeah, the data, it is good for what it does. Trying to move it away from the responsibilities. It will not work. >> REBECA FRANKS: Next question. How to start with Mull think module apps using hilt. >> MANUEL VICENTE VIVO: The best way to start, it is taking a look at the docs, the documentation is going to give you pretty much everything that you need. Regarding multimo Dulles, it works like if you have everything in the module, because, you know, different mo Dulles, they could expose bindings to different components in the same way. If you are talking specifically about dynamic future mo Dulles, we have a separate page in the documentation talking about it. I recommend you check it out. >> REBECA FRANKS: Let's talk a little bit about WorkManager then. The question that's come in, does WorkManager replace background servers. >> YIGIT BOYAR: If this is like the old services, Android, yeah. Absolutely no reason to do that. This is designed for stuff that should run, it is important to run it, and you can defer it. Those are the two key points of WorkManager. If it doesn't have to run like -- it is not any different than the background executor, anything that you dispatch to your query, the key thing there, something that you want to run, sending an email, this menu, then you use WorkManager. You can in the reold days of Android, there was a good reason to create the services, operating system, doing something, it is a stored element, I don't know if the operating system still considers them in deciding whether it wants to keep the application running or not. It is not really much reason to use them any more. Either use the regular executors if you didn't care about losing the work, if it is important to use WorkManager. >> WorkManager is supposed to be doing persistent work, work that you need to persist. Probably that question was more related to the recent changes, not changes, additions to WorkManager which was about to run foregrounds in business as well. Definitely you can use WorkManager for that and there are new restrictions happening and there are new APIs in the WorkManager version 2.7 that actually is with the self-expedited API that will help you out with the new changes in the language. >> YIGIT BOYAR: If the question is more about the foreground service, yes, and I go over all -- we wanted to have the foreground services early on. They want to work on the background, they have a reason that they need to show to the user, later we realize that it kind of gets abused by the applications and it creates a lot of noise in the notification. So now there is a new expedited job API and the WorkManager handles the back request whether you're on an older version or not, take a look at the release notes for WorkManager 2.7 and that will include what you need to adopt in the application to support the Android 12. >> REBECA FRANKS: Great. Let's to learn there. Are there any scenarios that need to be handled with live data other than using flows? >> YIGIT BOYAR: Wow. Not necessarily. The biggest difference between live data and flows is the data has preimposed limitations on how it works making this API simple, it is very opinionated on how to handle your life cycle, whatnot. They are all advantages of the live data and they are the reason why it does not scale so things like background, it is very, very opinionated. I think Jose from Android, they have a very good blog post on trying to convert the state flow and it explained the differences. I will say go read the article, if the use case, if you still believe live data is better for the use case, you can totally use it, it is not banned or -- not b bifurcated, but you get the workflow, you see the application, it is easier to maintain going forward. >> WOJTEK KALICINSKI: With the new API, the life cycle APIs that we have, they pretty much replicate what live data can do. Right. Before the API existed, live data, it was the simpler choice and now as said, you can get rid of live data if you want to and just rely on flows and the APIs that we have. Correct me if I'm wrong, I think that you have a talk about this where you explain some of that, right? >> MANUEL VICENTE VIVO: Yes. So the flows in practice, they have the flows in Android, go check it out. April. >> REBECA FRANKS: Hopeful those were the last live data questions. How can we reduce build times in Android studio? >> WOJTEK KALICINSKI: That's a big topic. We know it is both developers and the engineers of Google are working on this. The problem is that the build is not just one thing, it is everything from our plug ins and the compilers and the other components that build and package the resources, so on. We're tackling the problem one by one, I think the best thing that you can do as developer, it is to try to stay on the newest version so whenever we have new versions of Android cradle plug in of Kotlin, you know, the various things that you use in the build, any external plug ins that you have, try to update them, because oftentimes with new releases we either fix bugs like bugs that may be in later caches when they you shouldn't. We make the build incremental, and we work on the speed itself. There are new tools coming out, we will talk about that in he could, we will make the builds faster and certain scenarios, and that's the best advice. Also try not to do too much, try to stick to the declare active style configuration and if you need to do anything more, you would need >> REBECA FRANKS: Interesting , a lot to learn and a lot to prove, so much to cover for making -- for so many different things that you can do. Is there a smooth way to transition from legacy prejetpack apps to modern awesome jetpack apps? >> WOJTEK KALICINSKI: I hope you will take it. >> MANUEL VICENTE VIVO: There isn't a checklist that you can check that it is fully jetpack now. It is more of a case of me and my opinion, it is mostly all about your architecture, the architecture, it is able to scale and for example you depend on the interfaces where you can replace, for example, you know, the dependency, in your database, things like that, that's really setting up the app for success and make it able to scale. You try to do the good architecture, have it in place, you depend on the replaceable in the sense that if I need to replace, the preferences with the data store, that's a missing move. So that would be -- if you want -- >> YIGIT BOYAR: I guess we haven't been hearing this question much because we have a couple of years since we have started jetpack. One of the key things, if you're thinking about the specific jetpack library, when you write the replication, you try not to -- if there is a -- there is a well accepted library, a jetpack library, prefer to learn and use that instead of creating your own because you may feel more comfortable with the implementations, you know, or we spend a lot of time, effort, making sure that this library works in older versions, handling interesting cases, the foreground changes, it is a very nice example that happened, where it has changed in the platform and if you're using WorkManager, there are minor adjustments you need to face o support it, if you're not using WorkManager, you have to change the code to support that and that happens every single version. I try to use the jetpack libraries or the well-known libraries that are already supported by the developers to reduce your liability, your code base. >> MANUEL VICENTE VIVO: Test your code. That's really important! You want to make any change, you don't want to break anything. Testing, it is the -- it is the assurance that you have to do that. >> YIGIT BOYAR: And a good example use case, in jetpack, all of this, it is in opensource developed and we have it downstreamed branch that uses the Android source code master and runs all of the tests with that as well, just make sure that if something is going to break in the next version of Android, we actually get notified about it months, months before and we have to fix it then. There is a lot of confidence that when the new version of Android comes, you have to update the jetpack libraries and you're more comfortable to set the target version immediately to the new one after doing the update. >> REBECA FRANKS: Next question, does view models and hilt or dagger have a place in the compose world? >> MANUEL VICENTE VIVO: Yeah! They do. We actually recommend that, actually this is a shameless plug, but we're talking about the compose State of mind, where you talk about the different ways to handle the state complexity in compose and you're going to find things like composable, stakeholder, the -- the view model, it is supposed to be that stakeholder that's in charge of providing access to the business logic of the app and providing the UI state for a particular scheme. You can see that you will find view models at the root level of the screen, it could be a route if you are you using the composed navigation. They have a place in compose and please consult the doc. >> REBECA FRANKS: Okay. Cool. So moving on to something that was mentioned a bit earlier. Is there any bits on building multiplatform apps and the next question, also related, can we use this in KMM? >> WOJTEK KALICINSKI: Not yet. The multiplatform, it is something that we're looking into (Yigit Boyar) you may see this in ESV, it is -- we understand the developers, they're interested in the technology and the developers also use jetpack and we don't want jetpack to be a blocker, so you don't have to decide between this versus jetpack. Now, I want to highlight that when we do this, first we need to validate it, of course, and aside from that, if there is a library, a multiplatform, we need to make sure that it has no impact on the Android on the users. It needs to be a smooth transition, everything from the documentation to, you know, the API compatibility, they still work as expected for existing users. So it is not that straightforward for us to move the library to the platform. We're looking into the technology like trying to validate it, play with some of the smaller jetpack libraries to see how it works. So you may be able to see more on this in the future and right now, no, you cannot. We're looking into it. If you're interested, look into the EVCLs through GitHub, see what we're doing, if you can contribute, it is a long road ahead and we think the technology may work very well, we're excited about the multiplatform as well. >> REBECA FRANKS: Great. What is the best practice to handle the exceptions or other exceptions using Coroutines? >> MANUEL VICENTE VIVO: The best way is to just use the mechanism that coroutine provides you to handle the exceptions, that's the answer! We have a bunch of articles about coroutine and we have docs we have done in the past. They don't have to do anything, just rely on the mechanism that is built in in coroutine t will provide automatics for example, and you have to understand how the supervisor jobs or scopes versus others work, and all of that. You have the things you want to learn and everything makes sense after all. >> REBECA FRANKS: Cool. How do I automate the process of publishing an app on to the Google play store. >> WOJTEK KALICINSKI: I can take this one. So we don't -- I believe we don't have anything that's ready made like the Android studio or in Android cradle plug in for this. We know that it is something that the community might want, but actually there is a nice third party plug in that you can use together with the cradle plug in to automate this. You know, we may explore providing something like this out of the box in the future. If that happens, if we make that decision or not, you can use the opensource library for that. >> REBECA FRANKS: Cool. Is there a way to use the pag paginger class using a remote mediator, if so, where can I find an example? This is quite specific. >> YIGIT BOYAR: Right now, I don't think you can besides having a collective that requires the UI, you have the plans to create the paging to address the cases, because it provides some internal APIs that you want to expose it. Right now the ideal thing, it is just unit test for the remote mediator and the integration test, the actually paging, one of the things on paging, it is very, very UI dependent, it tries to optimize for what you are showing in the UI so without having that piece of the code, it becomes harder to control it. We know that we should have the testing library, so we're going to work on that. Aside from that, I would say either unit test remote mediator or integration test with the I. >> REBECA FRANKS: Great. Okay. What does the macro benchmarking library do? >> AMANDA ALEXANDER: For micro benchmark, this library helps you set tasks for both start-up, times for the app if you want to test the different stages of start-up, cold start, warm start, then also helps you to test Jank, the different frame performances of the app. If you have an app where there is a lot of scrolling, that's being done, you want to make sure that there are no dropped frames, it let's you help out the specific tests for scenarios that are more in line with how users are actual actually using the app and the user cases and scenarios that you set and target in the app and in terms of the measuring of those two things, those are the main things we're doing right now, we're looking at the other key performance metrics we want to track and to help you track within your app, and add that to the macro benchmark library. Right now we're focused on start-up and Jank because they're two performance metrics impacting the usability of your app and impacts the user metrics and we're continuing to expand that as well. >> REBECA FRANKS: That's super useful. Does data store support encryption? >> Not out of the box. We have thought about creating that integration as well. Right now, we use the data store, you can provide how you sterilize it, you can have your own encryption behind data store. There is no module that does it out of the box for you. It is super simple if you have an encryption library to inject that into data store. We're also looking forward to providing something similar to encrypted shade preferences and it will take a while because we want to add of shared preferences and make it a library by itself to support the encryption out of the box. >> REBECA FRANKS: Awesome. Thank you so much. Thank you. Unfortunately we ran out of time! Thank you for all of the questions. If you have any more, feel free to reach out to the panelists on Twitter if you have any further questions. Be sure to join us in the live stream! Thank you for watching! design team. on the material We would like to share a vision for how to bring beautiful design to an dried apps seamlessly with less toil. Building on a promise of modern Android development we have an opportunity to reimagine how designers and developers build digital products together. Today delivering a great mobile UI is a slow detail oriented process. It requires a ton of back and forth between designers and developers. Like most of you, our teams are frustrated with the time it takes to answer simple questions. What Typeface is this? What's the margin? How does this stretch? We're just copying values from emails, chat, tickets and it doesn't feel productive. We still sometimes have last minute scrambles because the assumptions were wrong. We call this the hand-off problem and developers tell us it is one of the biggest frustrations in building digital products. Some teams have been able to get around this through brute force and late nights and as customer expectations and the numbers of screens increase, it is getting a lot harder even for material on Google. Android gives the chance to reach billions of users, meeting them on phone, TV, car, watches, tablets, that's a huge surface area for your products and services. The challenge of delivering on the screens makes our hand-off problems unattainable. Today we're excited to share a glimpse of how material and Android are working to solving the hand-off problem for designers and Android developers in the tools that they use today. To achieve this, material design is teaming up with figma, leading UI design tool, FIGMA is excited about enabling new work codes and we're working to ensure that the design tools and developer tools can connect. We have prototyped a new work flow aiming to make hand-off a thing of the past. Our goal is to help teams build UI components together, starting in FIGMA, packaging for Android studio. Let's take a look. In our workflow, designers build UI components in FIGMA ready for production, this plug-in based workflow adds to the already robust model with annotations for enter actions and data. This creates what we call a UI package, developers bring UI packages into Android studio as composables at high Fidelity allowing us to immediately integrate components into the code base. FIGMA frames are comported and visual appearance properties, color, shape, they're preserved and responsive design intent like flexible rows and Columns comes across. Developers can use compose previews to see exactly what the designer saw, giving us confidence that the structure is right. Have you ever struggled with that first implementation because the imagery, the Typefaces were marooned in a design file someplace? We solve that had problem by bringing all sample images in Google fonts along to ensure you have the right assets in place. This workflow translates ideas, not just pictures, so when a UI package arrive, it feels alive and can be controlled the way developers expect. Designers and developers decide how data is wired up to UI elements. Text images and icons are marked as dynamic, Android studio helps developers see just which data needs to be provided. Interactions work the same way. Designers indicate which gestures to support in a per element basis, clearly marking calls to action in UI components to generate developer friendly APIs. In styles and the design, they become theme references in code, giving us visual consistency with the rest of the application. We want to give you the flexibility to build any UI you can imagine without reinventing the wheel. So when designers use material components like these in Figma, we make sure you get the real material design implementations in code. This is a new way of exchanging UI as an updatable package. When designers make changes, developers easily bring them in. UI packages are managed like code so teams can use familiar workflows for tracking and review. Cause Mottic changes don't require new code, just update, validate, go. Rather than requiring updates for everything, developers can override, remix elements to meet their needs. For example, we can add a specialized overlay, replace an entire section with the dynamic wave form rendering, developers decide how much or how little customization to apply. If there is one certainty in software development, it is the requirements will change. UI packages provide the flexibility with teams to meet changing demands quickly with minimal rework. The future of Android is bright with billions of users engaging with the products on an ever-growing surface area of devices. We believe that the new work flow break designer as and developers through the silos to deliver faster and with less frustration. We can't wait for you to restaurant problems into high-five, over the next few months we would like to work directly with a small group of teams as we prepare for a data launch next year. Thanks for watching. >> MANUEL VICENTE VIVO: Let's talk about compose State of mind. This is a State of any value that can change overtime. Apps are stable by nature, whether they store data locally or in a server, state is what makes them valuable. Let's look at jet snack, an app that's part of the samples, this is really important. You have the users and the shopping cart, this is a crucial role in most applications. The composition is a description of the UI built by compose that describes the current state of the app. Here you can see the composition, how it is visually represented with the shared screen. You can find the search bar, the divider, suggestions. All of that is part of the investigation of the navigation route of the app. In the frameworks like compose, you describe the app store in the state and the framework, it takes care of updating the UI for you whenever the state changes. For example, we're navigating to the screen, composing reexecutes that part of the UI affected by the change. Now, instead of search, the navigation host is updated to display the screen. This is a composable function where the state changes and recomposition takes population to display the new data on the screen. Let's focus on an individual cart item. It is an element that shows an item in the shopping cart, it let you change the quantity. With the build UI, you have the row and two buttons and a text. How do we keep track of the current quantify of the item in the cart? We see that nothing happens. When copying the inclement, these button, the quantity doesn't change. The function is not recomposed with the state change. That's because the quantity variable is not tracked by compose. Compose has a special state tracking system in place that schedules recompositions for any composables of a particular state. This allows compose to be granular and just recompose those composable functions that need to change. Not the whole UI. This is achieved by tracking not only rights, the changes, but also goes to the state. The composing state, the state types to make state observable. Compose, it will keep track of the composables that we have the value properties and you have the composition when the value changes. You have the initial value, here you use the value property to read and write the quantity state. You see that the UI, it doesn't display the state changes, this visual is that the function recomposes, quantity is initialized to one. In fact, this is a common mistake, that's why attempting to write this code gives this error. To use the quantity state across the composition, you have to make it part of the composition. To do that, you can start objects in the composition by using the remember composable function. It can be used to start both mutable and immutable index. Remembering the state, it is something that you must do for state that is created in the composition, it is inside composable functions. In this way, the state will be part of the composition and will be reused when the function recomposes. As you can see now, our item works as we expect, since the quantity is preserved across the recomposition, the values reappear on the screen. As bonus, you have the saveable, it is like remember but it will survive the activity and the process recreation. This is a good way for UI data to survive configuration changes. Remember this makes sense for the UI state like the item quantities or the selected task. But not for things like the element state. Also, you can use property delegates with the state APIs, and you can see that in action, with the key words, it is a nice way to not have to access the value property every time. This is the state outside of the scope of the composable function because composables, they can run frequently and execute in order. In our codes, mutating quantity, unclick is not a composable function. The state changes, giving the user inputs such as button clicks, using side effects, you can read more about side effects in our docs. The composable, it is not reusable in the current form, it is always initializing the quantity state to work, not every item in the cart will have that quantity to start with, but also the user may have items in the cart from previous sessions. Similar to what we do with the injunction, to make the cart item reusable, we pass the quantity as a parameter to the function. Not only passes touantity passes tots the work item should respect the single source principle. This principle, it courages structuring the code so that data is only modified in one place. If the card item doesn't own the state, it should not update it. Therefore, cart item needs to notify the triggering of the state updates. Now that the cart item is reusable, who owns that quantity and the logic to update that state? We can imagine that something like a cart composable should have the information of all cart items and logic to update them accordingly. The process follows to make cart items usable, it is called state hosting. We host the quantity state from cart item to cart. State hosting, it is a pattern of moving out of a composable to make it less and more reusable in the app. Stateless composable is a composable that doesn't hold any prior state at all. Composables, they should resist state as parameters and communicate events using the landers. This makes the composable more usable and testable as it is not coupled to any specific way of handling the data. The state that's hosting in this way, it should be intercepted if needed and complies with the single source of truth principle. Here we have the stateless version of cart item, you have the quantity to display the state and exposing the user interactions as events. Cart, it displays the different account items in the column, it is responsible for the calling cart item with the right information. The actual items on the cart, it was agregation data that we have from the cart remodel. For each item, we present the particular point of view. The logic to inclement or to look at the quantity, it is regulated to the model as the owner of the cart and data. State hosting is a pattern widely used in compose. You can say in most composed APIs to intercept and to control the state used by the elements. As intercepting state exceptional, before the parameter, they're a powerful language construct. For example, you need to control or share the coupled state, you can pass that in, if not, it is created by default. How high is the hoist state? It is a matter of ownership, when in doubt, it is the least lowest common ancestor of the composable that needs access to the state. For example, the lower common ancestor to the cart items is cart, that's the one calling them with the right information. The composable should take only the parameters that they need. We provide the stateless cart composable that takes only what it needs as a parameter. This make this composable easier to preview and to test. It complies with the single source of truth principle and it is more reusable in case we need to show it outside of another screen. If the window size is big enough, for example. Apart from this, it provides the rights and it is opinionated in the way that it handles the state and events. This version of cart, it is the cartless state composable using a cart view model that handles the business logic and the state. This pattern of having both the state and the stateless, the less stateful composable provides a good balance between being able to reuse the composable if needed and having an opinionated way to use it in the app. In this case, using the view models that are well integrated with the composed navigation, and to read more about the state and hosting, check out the documentation. State should be hoisted to enlist the lowest common ancestor, and should it always be in the composable itself. Let's examine the different ways to manage and to define the source of truth for different types of states. Composables, new element state management, stakeholders for complex UI element state management, and architectural components view models as a special stakeholder that provides access to business logic and application data for presentations. Before we start, it is important to define what we mean when we talk about specific terms. UI element state is the hoisted State of UI elements. For example, the state, the screen or UI state is what needs to be displayed on the screen. For example, cart UI state that can contain the cart items and it is crucial to the user are all in flux and this is connected with other layers of the hierarchy because it contains application data. The UI behavior logic, it is related to how to display the changes on the screen. For example, navigation logic, and the UI behavior logic should always live in the composition. This logic, it is what to do with the state changes, for example, making a payment or storing the user preferences. This logic is placed in the business or the data layers, never in the UI layer. Now that we're all on the same page, let's see the different ways of handling the state. If the UI element state harbors the simple, it can be placed in the composable itself. It is an example, it is not just composable, it is in the state. The state, you have the properties, all interactions, it should happen in this composable, otherwise we have the composables and they could mutate the state and that's not complying with the single source of truth principle and also makes the tracking down bugs more difficult. Really things can get more complicated, this is apart from the UI elements, it is in charge of showing the bars, navigating, showing up, so on. Having all of that in the composable, it make it is difficult to read and to understand. Following the separation of concerns principle, we can delegate the UI logic and the UI element state to a different task than we call stakeholder and the composable function is left to the UI elements. This state will be the source of truth for the UI element state and All State rights should happen in cyber class. This is a plane class that will be created and remembered in the composition. Therefore, it would be scoped to the composable that creates it. This is just a plain class, as it follows with the composable life cycle, it takes and composes the dependencies without working the memory leaks. They can have the composable properties and we have the recompositions in the chains. In this case, whether or not to show the bottom bar. It contains the logic such as navigation logic. We talked previously, the data must be remembered in order to reuse it across the compositions. It is a good practice, it may take the dependencies. We have the dependencies to remember as well to get a new state, the I appendixes change. We have the new stance, they use the -- we check with the UI elements and the core functions to trigger the reactions. In a nutshell, this is a plain class that hoists the UI element state and contains new UI related logic. This separation of concerns by reducing composables complexity and the favorable of testability, and it makes the hoisting issue as it is only one state to hoist instead of multiple states. State holders can be simple and focused, for example, this class for a screen, it only contains the list of active Fielders and shared results. The state holder will help you to manage the complexity when you need to track the state or UI logic. Apart from state holder, we explain the architecture components and the model class. View models, they are used as state holders for states that are determined by business logic. View models have two responsibilities, first, providing access to the business logic of the application that is usually placed in other layers of the hierarchy such as repository or use cases. Second, preparing the application data for presentation in a particular screen. This is the UI state of the screen, represented with an action type. In a peer compose app, we use the compose state apps and in a hybrid app, you have the construct, like the state flow. View model, they have the configuration changes and they have a longer lifetime than the composition. They are not part of the composition, therefore they cannot take state to the composition, for example, it remembers value. Be careful, this could case memory leaks. As you can see, the model it's depend on other areas of the hierarchy, for example, repository, use cases, and remember that if you want your UI to recompose when you have changes, you have to use the composed state API, and in this case, since the UI state is kept outside of the composition, it doesn't have to be remembered. You can just consume it, the function will reexecute when it changes. Other areas of the hierarchy, they have the streams of data to prevent changes. It is possible you already have an overflow in the models. The streams of data also work with compose as they are helping functions to converse the streams of data to compose the observable state AP Is, for example, collect the state, collect values from the flow and you have the recomposition every time a new value is initiated in the flow. In summary, they are of the composition and they have a longer life span. They're responsible for the business logic of the screen. Deciding what data to display. According to data, preparing it for presentation, this is recommended for screen level composables. The new models have benefits of the plain state holders, they survive the configuration changes. They're well integrated with other jetpack libraries, such as hilt and navigation. With hilt, you can get new models using the dependencies provided by hilt with the line of code. navigation, you have the new models when the screen is on the back slack, knowing that the data is available when you return to a destination. The view model is clear when the destination is on the back stack ensuring that your state is automatically cleaned up. All of this is more difficult to do with state holders that follow the life cycle of the composable stream. That said, if this benefits to the use case, they do things differently, you can move new models' responsibility to the state holders, whatever works best for you. It is also possible for a screen layer composable to have state holder and a view model since the new model is longer, state holder could take the view model as a dependcy. Putting this into practice in addition to the current view model, we had in the composable, you can have an additional state that contains UI element state and the logic, for example they may see the list state to know about the position in large shopping carts, resources to format the messages and the prices and the State of each item to expand to show more information. Both view model, state holder, they have placed in cart, they have different purposes and they can work together. If we look closer at the life cycle, the cart state will follow the life cycle of the cart composable. It will be removed from the composition when the cart is placed. Cart view model, it is the copy to a different life cycle. That of the navigation destination graph, fragment, activity. Looking at the big picture, the role of it, it is clearly defined. From UI that contains the UI elements to the data layer that contains business logic. It selves a particular purpose. Here on the screen, you can see the different entities with the role and the potential dependency relationships between them. Hopefully the table I showed before makes more sense now, keep it in mind for future decisions to have a clear state management story and architecture. The state, check out the word docs, code lab, samples. Thank you everyone for listening. I hope this talk helps you to get into a composed State of mind! Happy composing! I'll talk to you soon! Bye! compose basic dialogue. I'm Florina Muntenescu, a developer relation engineer and I'm joined by Jolanda Verhoef, also working as developer relation engineer. >> YIGIT BOYAR: Hey, >> JOLANDA VERHOEF: We'll be live programming some challenges you have when you start using the app using jetpack compose. >> YIGIT BOYAR: As she's coding, open up the Android studio, follow along or you can just sit back, watch, do the code yourself at a later stage. We'll look at the live chat, if you have question, go ahead and lace them there, we have colleagues answering them there and if we see that there are a lot of questions being asked related to this code, we'll answer them here. >> JOLANDA VERHOEF: So during this session, I will be sharing my screen to make sure that you can code along. Let's get started. We will open up a browser first, we will search for the jetpack compose basics code lab. That's the code lab we'll be following today. Let's look that up. Let's open up the code lab. There we go. >> FLORINA MUNTENESCU: Throug h this session, we'll start with a new compose project, we'll see what the Android studio generate has and we'll learn how to reuse composables, adding columns and rows, and then we'll dive into state and compose and learn what state hoisting means. We'll finish by creating a performance persisting the state and looking at the list and the app, depending how much time we have. >> JOLANDA VERHOEF: Let's go into Android studio, we'll open up a new project. I will be using Android studio Fox here, the latest stable version and we'll start a new project. Earlier on, we worked with Android studio and you can also use new project instead. Let's go with new project here. Let's see what is created. We have to choose a template. We'll open the empty compose activity template. This setup all of the boiler plates we need to be able to use the compose app. We precious next and will choose a name. We'll go with basic code lab. That's the thing we're building right now. You can choose another package name or location if I want to. I will just leave this as they are. A minimum STK, you make sure you have the API21, the lowest supported version, if you want to go high, that's a possibility of course also. I will press finish here. While this is being set up, I'll go back to the code lab. I will ask a question. Tell us a bit more on what compose actually is. >> FLORINA MUNTENESCU: Yes. So jetpack compose is a modern toolkit presented by Google to simplify the UI development. It uses a reactive program model. This composes the full UI framework, you describe the UI calling a series of functions that transform data into UI hierarchy. When the underlying data changes, the framework automatically recalls the function, the functions updating the view here. All right. Has the project built? Can we see how this looks in the project? >> JOLANDA VERHOEF: Almost there. We can already see the main activities. I think we can continue. >> FLORINA MUNTENESCU: Okay. So composing, this is the so-called composable functions. So these are actually just regular functions, and they're marked with the composable annotation. Each of these call other composable functions, like here the text. A function is all you need to create a new component. Say composable functions, it is quite long and we'll call these composables for short. >> Let's take another look at the main activity. As in the world, the activity, it is still the entry point for the duplication. So the activity, it has a create method, creating the applications. Inside of the method, you can see the set contents call, that is our way to move to transition to the compose world. Within that set content block we can start calling composable functions. Inside here, to the bottom, you see that the greeting is called, the composable function that was mentioned before. Surrounding that greeting method is surface. The surface is a kind of a container composable. This is also a composable and I'll quickly dive into the actual implementation with control B to see what that looks like. As you see, this is a composable function and it has a lot of failures to set in order to adapt the values of that surface. In our case A lot of these, they have default value, we don't have to adapt them, they have reasonable defaults, and we can change things if we want to. We'll see what else we have here, we have the basic code lab team to style this, to give it a attorney material styling and we'll talk about that a little bit later. We can run there on the immolator and device, we'll do that later. We can also use a preview, which is directly inside studio and I'll open that, this we'll build for a bit, and you can see that you can create another method and just call it preview or whatever name you want. Just make sure it doesn't have any parameters. Inside you can also call this composable methods and it will actually generate for you a specific preview that you want. While this is building, let's take a look at what else we will be doing. >> FLORINA MUNTENESCU: We have a circle project, but you will see when the project builds, you see this is a great thing and so I think we should start updating the UI and changing the color of the greeting. >> JOLANDA VERHOEF: There it is. >> FLORINA MUNTENESCU: Yes. There it is. >> JOLANDA VERHOEF: There we go. >> FLORINA MUNTENESCU: Yeah. >> JOLANDA VERHOEF: I think -- we have. >> FLORINA MUNTENESCU: We have a text on the screen right now. >> JOLANDA VERHOEF: How do we tweak that? What do you want do to it? >> FLORINA MUNTENESCU: Let's change the color of the greeting and the spacing around it. >> JOLANDA VERHOEF: So the first thing we want to do, let's say that we start by changing the background color. As you see, this is now just plain white and let's try to make that a purple color instead. What we can do, in order to get that done, we can use that same surface that we were using before. So we can actually surround our text and we can surround it with a container. In our case, the container is the surface container, it is the material component we can use and you set the colors for the container and you have whatever you put in there, you put it on top of that color. In our case, you set the color of that container to be -- I'm using the material theme here, this is again a little bit above the styling of the app. So we will use the color primary here. If we use the primary color, we can use the different colors from the material design, it should actually update the background of our surface. One thing that you might notice as well, if you look at this, it is that it is not just changing the background color but also the text changes as well, it is now white. The material design, it is an opinionated framework, trying to do the best things, it tries to make sure that even if you do not make a lot of changes to the code, it actually does them for you and tries to behave in a logical manner. In this case, what the surface does, you go into it again, when you set the color, it chooses the content color for you, it uses -- it calls the function to see what the content color should be. In the first case, we have the white background, using black, and in the case that we use the primary color from the theme, which is verbal, it actually chooses the white color on top. This way we create a nice UI. Now we want to add some spacing around this. This actually is the second big concept of building UI with compose and it is modifiers. Next creating composables, the composables, you can also add modifiers to basically all of the composables and the modifiers you can set and they basically modify the composable which is wider qualifiers, and that's a lot of them. You see the focusable modifier, the clickable background, a whole range of different modifiers that in some way you modify the composable that they're being set on. In our case, we want it add spacing around our text. We will use bedding, and the bedding we set is the 24db. In the meantime, if you get stuck during the building this, if I'm going too fast, if the code lab, there is a lot of places where there is a bit of code of where you should be at that moment. When you get stuck, you go back to the beginning or through the step in the code lab and you copy and paste this. Let's see. While building, it has issues with importing. There we go. It uses all of the imports from the composed libraries to get things done. In our case, I think it is having issues importing the 24DB. While it is building, let's go back to the code lab and see what the next thing is that we want to do. >> FLORINA MUNTENESCU: Maybe we can copy and paste from the code lab just in case it is not exactly there. >> JOLANDA VERHOEF: There we go. >> FLORINA MUNTENESCU: We mentioned there was a lot of modifiers available. We actually created a cheat sheet for you to easily find some of these modifiers available, check out the documentation for a cheat sheet on all of the modifiers available and what you can actually use in compose. >> JOLANDA VERHOEF: In the meantime, I got it done, the spacing is showing around the text and it is nice and purple. Just the way we wanted to design it. >> FLORINA MUNTENESCU: Awesom e. We actually got one question on the live stream. Do we actually need to wrap inside of the composable always in the basic theme or is it enough to Just Do It in the main activity? You don't have to do that I think in the next step, we'll start to see how we can reuse composables and we'll start creating multiple composables and you will see you don't have to do this for each of them. I don't go further into that, we may have time do that at the end of the call. Right now we have one composable. With time, the more components you have with the UI, the more levels of nesting, upgrading, pretty much the same with any other function in the code base. The problem, this can affect the readability of a function becoming really large. By making small reusable components, it is easy to build up a Library of the UI elements using the app and then each one can be responsible for one small part of the frame and then it can be edited and previewed independently. >> JOLANDA VERHOEF: Let's try that with our code. Of course, this is just going to be a tiny extraction of a little bit of code. Indeed, when the code is bigger and bigger, you want to extract the code more and more often. In our case, let's extract most of our app into a composable called my app. So I will use a live template in order to create a composable function and you can just type this out if you want. We'll call it my app and we'll extract this whole piece, the surface and the greeting inside of it. We move this to my app and instead we go my app directly here. Now I did a simple extraction in the separate composable. This is mostly, this is not changing anything in our design, but this is mostly to demonstrate how to actually move the composables outside of each other. >> FLORINA MUNTENESCU: We have learned how to use composable functions, modifiers, we reorganized the code a little bit. In the next section, let's increase the complexity of the UI. Our goal is to create a UI like the one that is shown right now. We have two greeting buttons and spaces. What do we need to do, to build this UI, we'll use more base composables provided by the library. Whether you use a column, which lays out the children vertically, and then inside the greeting, we will use a rope that lays out the children horizontally. >> JOLANDA VERHOEF: Let's look at the design again. We want to create the two hello world and hello compose items. Somehow we need to lay them out vertically and then inside we want some horizontal alliance. Before doing that, I want to make one more change to the code. That's what I will do to adapt preet view n is still calling greeting, and we want this to go to my app, that way when we make changes to my app we will actually see those in our preview. We could add another preview if we want to, we can choose how we want to create previews for the app. In our case, that's directly called my app here. The first thing that I want to do, based on the design, it is I want to break up our hello Android into hello world. Two vertical texts instead. The first thing that I'm tempted to do, it is to basically just copy my text and use it again so that I have two texts. Then change the first one to be hello, comma, the second one can be just the name. Right. Here we will just use the name that's being put in to the greeting. Now let's see what that would look like. I think it must look quite nice. I do see that we have the bedding here two times. Probably there will be -- oh, actually, there is -- they're on top of each other. That's not what we want. That's the thing we mentioned we want to align them vertically. What surface by default, it behaves like a box, laying children on top of each other so that you can align within that box. What we want to do, we want to actually lay them out vertically. We want to surround this with a column. There we go. Now I do expect them to show up on top of each other. Within the column it basically looks at which composables are here and then just puts them underneath one another. This starts to look a lot better. We do see that the bed something now done for each of the texts individually and I think we may want to move that into the column, so that the hello Android is nicely put together. Let's move this into our column and Cleanup a little bit. We can simplify the texts, there we go. Then the modifier can go as well. As you see, by just adapting our code, we can easily change what our design looks like, you can see it directly in Android studio. I have not ran this app on any device yet. So the first thing we wanted to do, I think that looks quite nice. We'll take another look. We'll get to this point. . The next step, it is let's try to create more than one greeting. We'll try to put in dynamic data here. We want to Mick s make sure thate have it with the words composed. We're not adapting that greeting itself any more, rather we'll make changes due to the my app composable. What we do, we simply add another greeting here and in using Android, you use worlds, and we use compose and we have the same things that we did with the text. We surround this with a column again, then those two greetings will show on top of each other. Of course, this is fine. What if we're going to have ten or 0 of the greetings, that wouldn't really scale, right? So what we can actually do, we can put the names into the my app composable as a parameter. Let's give the my app composable a parameter called names, it is a list of streams, this way we add two, three, whatever we want. We give it a default value. We'll pass worlds and we'll pass compose as the default value here. Instead of creating this greeting by hand, by duplicating it, we can actually be able to surround this with a four loop. This is a normal construct that we can use. Instead of having to do something fancy, we can easily just use the loop and then it will for each name, it will call the treated growthing and put it as a child of the column. Now I'm still calling this world, so it leads to worlds, we'll call that with a name and then I would expect this to give hello world and hello compose. Now this has different sizes, as you see. That's because by default, the column, it is just using whatever space the children need. In order to demonstrate it better, let's for the preview go to the width of 20 pixel, kind of like a small device and if we scale this, we can see that it has the 24 pixels of bedding and not any more. If we want to change this behavior, we want to modify one of our composables. We want to modify the greeting composable. with this. We can use theier fill next modifier, it tells compose to use this basically full width that's available in the parent container. So let's see what that would look like. The column now fills the whole bid. Because it is inside of the sur far, the surface has the background color set, everything will be that same color purple. That starts to look a little bit better already. I do see that everything is purple now. I think in our design we had some spacings around this. So we want to adapt our compossibles a little bit more. We want to modify them a little bit more. In our case, we want to add some extra bedding surrounding our surface so we can use another modifier for our service and we can use modifier again with bedding. As you see, there is different bedding methods here. We can use all, horizontal, start, top, end, et cetera, we can choose which one. So in our case, what we can do, we can set the horizontal and the vertical value here. Our horizontal could be for example ADP and then our vertical, it could be let's say 40. Let's align this and let's run it again and see what it looks like. I'm expecting this to add spaces in the left and right of the greetings and also a little bit of spacing to the bottom and top. That starts to look quite nice. The only thing I'm missing is a little bit of extra space on the bottom of the whole app. What we can do, we can go back to our app and we can give the column a bit of extra bedding as well. We can create a modifier here and say let's do extravert Cal bedding of four more DPs. That way I think we have the spacing down. The only thing that's left, it is to add the button. We have been working with Columns first, so let's try and create a row. Let's see where we put -- this needs to be inside of the greeting. Inside the surface, it is inside of the purple rectangle that we have and then it should be somewhere after the column. Let's add it over here. I'll just create a button which has been -- you have the click listener. This is a call back. We will actually fill this in later on. So far we're not dealing with the behavior of the button yet. Inside of the button we put whatever other composables we want. In this case, we're just going to add a simple text composable which will say show more. There we go. We can also put, I don't know, a whole other UI hierarchy again inside of that button. That works quite nicely. While we do this, I haven't laid out this button in the parent yet n button will be just shown on top of our hello worlds text. We probably want to do something special here. It shows just on top of the rest. You can also see that it currently has a pry pair color and that's because of the default button, the default uses the primary color. We can use the outlines button instead, it is another concept from material design which will use the surface color as a background and it will give us a nice wide button that we saw in the design. Now we want to put this in a row as we discussed. Let's put both our column with the text in it and the outline button together inside the row. I'll do another surround with widgets. We'll surround this with a row. This will probably not work yet. We have made the column fill the next width. What this is going to do, the column, it will fill the whole width and there is no space left for the button. Instead, what we can do, we can actually go and remove that film, there we go. Again, it won't use the full width, we can use not a modifier instead, it is the weight modifier. The weight modifier, you may still remember it from the view system and it tells the parents, the row in this case, that this child, our column, it wants to be flexible, it wants to take up any space that it can but it doesn't want to overlap with other children. This is making this Column flexible child while our outline button is not flexible child. Our outline button would just take the space that it actually needs. As you see, this starts looking much better. The only thing, the button, it is aligned to the right top and that's because it is our column that has the 124 pixel bedding. We want to move that to their whole row. Let's move it out here. Inside our row, let's add the modifier, bedding, 24DP. You see this DP handles the whole independent pixels, it is quite nice. This is starting to look like it. Let's take a quick look at the code lab to see if this is the same. >> FLORINA MUNTENESCU: It is! Yeah! Yeah! Cool. Awesome! We have a question around XML, it is composed total KML free or in some cases we use the XML? >> JOLANDA VERHOEF: This is not defined any longer, you can use this, but apps use XML for things like strings, these kinds of resources. And it is possible, of course, to interop if you have a lot of XML views, you slowly want to migrate to compose, you can actually still call your XML from within compose and the other way around. There is a really great other code wraparound this, around migrating the app to compose. >> FLORINA MUNTENESCU: There is a code along on migrating to compose tomorrow. I think also things like the Android manifest will still be using XML of course. Yeah. That's the default in Android. We're starting to answer more live to the application. Let's move on. There is a lot you can do with the composables and modifiers. For now, we actually haven't added any behavior to the app. Let's see how we can expand the greeting when the user clicks the button. The text inside the button should also change, right, should we see either show more or show less depending on what we have. Before getting into how to make a button clickable, how to look at an item, you need to store some value somewhere that indicates whether each item is expanded or not. This is the state of the -- since we have to have one of the values for a greeting, the logical place for this, it is inside of the greeting composable. As we mentioned before, composed apps transform data into UI by calling the composable functions. If the data changes, compose reexecutes the functions with the new data, creating an updated UI. This process that I just mentioned now, it is called recomposition. Compose also looks at what data is needed by an individual composable. It only needs to recompose components where those data has changed, and the composing are the ones that are not affected. This also means that composable functions can execute frequently and in order. Please don't rely on the ordering of the code that's executed or how many times the function will be recomposed. Let's see how we implement this space in our greeting composer. >> JOLANDA VERHOEF: That's a lot of theory. Let's see how we can actually implement this. So this is step 7 of the code lab, if you were stuck, bottom of step 6 has great codes to copy over and you can continue with us from step 7. What our goal is for now, we have this beautiful button that says show more. We actually want to be able to press it and then it expands the row, our greeting, and it has show less. If you click it again, it will change the button again. That's how we can actually use state. Let's see what's the most -- the first intuition, it would be -- well, I want to make a variable which we call -- it is called expanded. It starts being false. We're not in the expanded state initially. When I click the button, I want to change this, the expanded state would be whatever it wasn't before. Right. Negating the value, setting that. Let's for demonstration purposes indeed show more or show less based on that expanded state. If expanded, I would say show less. If not, I would say show more. This code actually will not work. I will quickly run it on my emulator to see if it works, but I can it will you already that it won't. The reason for that, what was just mentioned, it is that just setting a value here is not actually going to do anything. What we need to do, we need some way to tell compose that when this value changes, it needs to recompose any composables that depend on this and in our case, the composable, the composable that depends on this value, it is the text. The text changes, when the value of that variable changes. In our case, when I just have this button, I press the button, maybe my expanded variable will change to true and it doesn't mean that the text composable will be recomposed and thus show different text now. We need some way to signal to compose that this is a value that it needs to kind of keep an eye out for. The way we do that, we use the mutable State of. This is a composed method that you can code with initial value and the unmutable State of signifies that this is a value that actually needs to recompose its dependence when it changes. This now returns us to states, instance, instead of just this. So that means that we cannot just call it like this, you actually set and get the value of this. Although this all looks quite nice as you see, it already shows us a big redline here. It is not just to use the mutable State of, and the warning actually says that we need to use the remember keyword here, and remember is used in compose for another -- it has a lot of purpose. Let's take a look at what remember does. It is imported. Let's see what it says. Remember, make sure that when this greeting is being recomposed, not the text that depends on the expended value, but when this greeting appear, it is being recomposed because for example the name change, or because of whatever other reason as mentioned, this can recompose as often as it wants. Remember, make sure that the value that's created inside it will not be reset every time that this composable is being recomposed. The first time this greeting is being called, it is the initial conversation, it creates the mutable State of, and then when the greeting is being recomposed, it doesn't actually do that again. It doesn't reinitialize to false, instead it remembers what it had before. Remember is a great name I would say for this. We can actually use the viewer here that give as state inside of this composable that will actually work. Let's check if this actually does work. I'm running that on the immolator as we speak. It will reset and while it is doing so, let's see if clicking the button now actually changes the text that is shown on the button. There we go. As you see, when I press show more, it changes to show less. That's amazing. Now the only thing that we should actually also do here, it is to change the bedding. So let's create a variable called extra bedding, and we will make -- well, it depend on the expended value, yes. If this is expanded, then this is going to be let's say 40ADP and then L0 and we have to use the dotted value here. There we go. This extra bedding, let's set it to the column using that extra bedding, and you have the bottom of the column so there we go, we have that set to the extra bedding and realign this a little bit. There we go. Let's run and see if this actually works. One thing you may notice, I'm not using the remember value here. That means that every time the greeting is being recomposed, if you remember correctly, this variable, it will be recalculated as well even though maybe our expended state did not really change. In this scenario, we're just doing simple statements, it is not a very complex calculation. If this calculation is way more complex, would take more cycle, we can actually opt to put in in a remember block. You see the bedding expands and collapses. >> FLORINA MUNTENESCU: In the state -- in the case of the expandable greeting, our state, it live there is inside of that greeting composable. You can write and read the value of the extended state only in that one composable. There is no need to know about the state in URL, this is really specific to the working. In general, it is modified by multiple functions, should live in a common an scattered showers, a function that calls the greeting. This process, and this is called hoisting, to lift, to elevate, making state hoistable avoids duplicating the state and introducing the banks, and also help us to reviews the composables. It makes the next composables substantially easier to touch. The state does not need to be controlled by a composable parent, should not be hoisted. It is the case for the greeting. Keep in mind that the source of truth belongs to whoever creates and controls that state. In the next section, what are we going to do. We want to build an onboarding screen. Whether we want to show the onboarding screen or the greeting screen, it will depend on some state as well. How do we do this? >> JOLANDA VERHOEF: Well, let's first start by copying over the code for this onboarding screen. We have already dived quite deep into designing screens so I will quickly copy over the implementation here. You can do the same if you're following along. Let's copy over what we have and we will quickly walk through this. I will put it below our greeting and above our preview. Let's put it over here. I didn't copy it correctly. There we go. What are we doing here? You see at the bottom we're creating another preview, this time setting the width and the height. While we're going, let's hide the immolator for a bit and let's take a look at the preview. There are still some errors here, we have to add some imports. You want to import, get the value, unmutable State of. We also want to import set value, there we go. We want to import the fill next size. That's close to the -- there is an error arrangement, alignment, all of these settings, certain values for our design and I think that's about it for our imports. Let's take a quick look at this. The first thing that I'm noticing, it is that here I see again that same concept of remember mutable State of, in this case, setting the default to true. Here I see something else. That we didn't see before. I see the key words. Maybe do you want to explain what this keyword does? >> FLORINA MUNTENESCU: Sure. Sure. So it is using delegates. In this case, when we would be using should show on boarding, we no longer use the value like we are in the greeting. Actually, can I change the remember and the ways to remember in the briefing? Yeah. >> JOLANDA VERHOEF: Yeah. Let's. >> FLORINA MUNTENESCU: Here, let's use -- let's see what happens. I think we'll need to use -- yeah. Now we can remove the value. >> JOLANDA VERHOEF: Let's take all of the values that we have. There we go. >> FLORINA MUNTENESCU: Yeah. Using the property delegates allows us to simplify the code a little bit. >> JOLANDA VERHOEF: Thank you. That actually looks a lot better. I was already getting a bit more of the writing value everywhere, I'm happy we got this fixed. Okay. That was the first thing I saw here. There is a big to do here, we'll get to that later. Let's take a quick look at our design. You see that we have a surface again so it was the container from material design and then we have a comma in this case, it is filling as much space as it can. In our preview, we can see that it is 320 by 320 pixels and it is using a vertical arrangement and a horizontal alignment. So vertically, what this is doing, it is trying to center the children in the center of the column. Then horizontally, every child within the column will be also centered. In the end, that leads to this result, our text and our button, nicely in the middle of our container. As you can see, there is a butt of spacing between our building button and the text and again we're doing that using the bedding modifier. One more thing you see on the button, you have the click parameter again, and you click parameter itself, it gets a method, gets a function actually. This the call back which actually tells the buttons that when it gets clicked, it should call this function, it should execute what happened inside N this case, we're setting the onboarding value to false. So that's what this currently looks like, but we have the onboarding preview, if I run the app, we're not going to see this onboarding, this onboarding screen is not used anywhere. In order to use it, I think we would have to make -- make changes to my app. The first thing I'll do, I will just actually change the name of my app to greetings and this is our column which had a list of greetings inside. Then we will create a new my app composable. Again, I'm using the live templates here. Creating a new my app. The function, insights, you will have some sort of logic to either show the onboarding screen or show the greeting screen. It should be if should show onboarding, if we want to show the onboarding, then we would call the onboarding screen and else we'll call the greeting screen. This is the state that was mentioned, right, do we want to show the on boarding, yes or no? That floor that we had inside of the onboarding screen, it doesn't really belong there. Let's hoist this state. Let's move that to the point where it actually needs to be read. In our case, that is the my app composable. How do we set this? We pause our state into the onboarding screen composable. This is not what we want to do. We want to make sure that the composables are clean and like boxes. You shouldn't be putting in the state that could change from within the composable. Instead, what we do, the same as the button, we put in the call back, in our case, we create a call back calls and the continued clicks. You give the call back, it should set the onboarding to falls. This is the not the parameter yet, so add that to the onboarding screen. Inside we can say continue, click, this is a function. This is our way to define that this is a function and we're passing a function and in this case, a call back, because this is called from within the composable. This call back, it can be removed and instead we forward that and continue the clicks here. Now if we can run this app, inside our emulator, we should be able to work with this. I do see that there is still an issue here. In our preview, we're not pausing anything for the uncontinued click value, let's pause something. In the preview, we don't want to act on this, right. Nothing should change, I just want to show the onboarding screen. We have the empty call back here. I think that fixes it. In the meantime, we sped up the emulator, we see what this behaves like. We're opening the -- let's go back to the top. We're opening my app, inside of my app, we have this state which starts as true, we should be showing all morning, that even if this is evaluated, rather than hy hiding things from the composition, we're dynamically showing certain composables, we're adding the composables to the composition and we're removing them whenever we're done with them. In this case, whenever this value changes, this statement is being reevaluated and if the value changes from true to false, this will just not be called any more, it is just that the on boarding screen composable will leave the composition and instead the greetings composable will be added. Let's see if that actually works. In our emulator, when we press the continue button, it is the clicked call back, and there we go, it calls the composable. In this case, we use a basic value to work with, this of course, in a bigger app, you may want to start working with the identification library, and this is just to show you how the app can work with states on a higher level. >> FLORINA MUNTENESCU: I want to point out one thing you have done here, you copy and pasted the code for the onboarding, you copied and pasted the preview. That's cool, if you switch back to the preview, we can actually have multiple previews in the same file. Actually even the same composable, we can have multiple previews. This is so needed. You know, you don't have to go all the way to the app and navigate to the greeting screen to be able to see how that looks. We can just look at the preview and, yeah, it is easier to debug the code. >> JOLANDA VERHOEF: Should we add another one? Another preview can be added on top of this one. I'm literally duplicating the first one and for this one, for example, we can use -- we have the show system now, we have the -- he have the UI mode. Yes. There you go. This should be UI modes, yes. We can actually show our dark theme inside here. Let's rebuild that, see what that looks like. For the onboarding preview, I have another preview annotation and I'm adding the UI modes which means that we're actually showing the dark mode here. Let's modify this a little bit. There we go. >> FLORINA MUNTENESCU: The live chat, they're confused, we don't have separational concerns any more. That's true for this code lab. Keep in mind, here we're just showing the first steps with using compose, and it is normal. We have content showing separation of concerns, how to use this state in depth. Check out the other code labs and documentation. >> JOLANDA VERHOEF: Ky add one more thing to that? I think what I wanted to say, it is like if you're being more -- if you're starting to create a bigger app, compose is a UI layer. There is -- there still will be a few model, there will be repository and you will build this the way you were used to and you're changing the UI layer. You'll be interacting with the model to get the data and then show it in your you can I layer inches others say the Android, they're a beginner, they're in the progress of completing the pathway from 2020, which is using XML for activities and they're asking us if it is recommended it avoid the XML to use compose instead? I think you will see XML in apps for a long time. Keep an compose, it is building up fast. We see already tens of thousands of app, more than 10,000 apps on play store using compose. The play store is all built on compose. Okay. We went through several things. What do you think -- what else should we -- we have the recycle before this? Right? >> JOLANDA VERHOEF: Yes. Indeed. So we have been showing so far, we have been showing two greetings, right. We have just the hello world and the hello compose. Let's spice things up a little bit. Let's, you know, make a list of 1,000 elements. I'm going to warn you, if you're coding along, don't run this on an emulator yet. The computer may get a little bit hot. Let's code and see -- create a list of 1,000 elements and we can use the list builder here and we can say that for each one of those thousands anterior going to create a string and in this case, using the widgets and the value of the index. This will create a string within the number 0, 1, 2, et cetera, all the way up to 999. If we were to run this, then this loop would start doing a lot. Yes. It would go through 1,000 values, and for all of those create this greeting composable. It is a little too much. Composables, they're cheap to create but not that cheap. We do want to be a little bit careful here. Instead of using this loop, we can move to something else that is called a lazy column. The word lazy already kind of maybe gives it a way a little, the lazy column, only renders those composables, only creating those composables currently in this screen, that are currently shown on screen. What we can do inside of the lazy column, directly creating the greetings in there, we can use the item column and you can create one item or you can create more than one. In our case, we want to create more than one. For each of the name, we want to create a greeting so we can use items here and then there we go. We can say for each of our names we will call that name and then we will call the greeting for that. So this is actually using a DSL, it is a very complicated way of saying that this is not directly calling composables and it uses items or if you want item, it is also an option or you can work with index items in here. That's all tied to that lazy column. Same way by the way you could also create a lazy row. So let's run this on our emulator and see what that lazy column will do. Now it is safe again. You can run it just how you want. Let's see -- let's spin up the emulator, we see what the list looks like. >> FLORINA MUNTENESCU: No more recycled view, I can actually be lazy? >> JOLANDA VERHOEF: You can be quite lazy. True. Let's see if this works. There we go. We have a huge list here. For each of those, I can open, expand them, I can collapse them again. Just to show you a little bit more of the strength of that, we can also say that we want to get header here and we will just say that we want to show a text that has a header here. If we want to, we can even work with sticky headers, there is quite some fancy functionality in here. This just adding that item here, whatever the composable is that you want, it will give us the ease of mind to work with the lazy column and add it to the top. As you see here now, we can see that there is now a header and it scrolls along with the rest. Isn't that amazing? >> FLORINA MUNTENESCU: Should we say how we persist the state? >> JOLANDA VERHOEF: Yeah. You might have noticed already that -- of course, every time I run the app again, it starts on the onboarding view. Actually when we would rotate our screen, when you would move to dark mode, let's go into the list and as a demonstration, go to dark mode instead. What it does, it will actually reload the activities. That's something that happens if your configuration changes and what actually happens, it is that the activity will be reloaded. Currently in our app that leads to the composable being recalled again on the highest level and we are back to the original my app which then has the first mutable state to true, we see the onboarding again. That's not what we want. Right. If you rotate the screen, you change to dark theme, then we want to be able to remember where we were. This is actually quite easy. We were using the remember keyword here. Instead we choose to remember saveable, and remember saveable, it is simply going to remember the value that's inside, but also contained over configuration changes. If we now run the app, we go to our list, then we rotate the screen, we move back to live mode, I would actually expect that to stay in the list, and not go back to the onboarding. Let's see that in action. Let's continue to the list. Let's scroll a little bit. Let's change back into our live theme again. There we go. There we go. We're still on the list. This is just one change in a word here and that made it survive the configuration changes. >> FLORINA MUNTENESCU: Okay. How about separating the app and adding dimensions? >> JOLANDA VERHOEF: Yes. Let's add auto medications. I would love to add an auto medication for our expanding action, that action, it is now simply setting that value to 248 as 0. We can animate that value. Let's go into the greeting. That's why we were setting the expanded value. Inside our extra bed, instead of just setting that to 48 or to 0, you see capability medication here. There are all kinds ever different obstructions for animations, and we're use low level one, it is simple to understand. We will use animates -- animates the deep states. This is doing something similar to what we were doing before, it actually -- when I finish that up. No. Almost. Almost. Almost. It is -- setting the target value. This is the value. Sorry. I was -- so enthusiastic about all of the blocks of code everywhere, but this just needs to be irregular round brackets. The target value is set for 48 and 0DB, what actually happens, it is animating the DPS state, it will return as state, it is the same as we have had for the expanded value. We can also do the same with property delegation, we can use by here. If that happens, if you set this value, if you expand the changes from false to true, then this target value, it will change from 0DP into 40ADP and the state, it will start with new values in that state, and the constructs, every single frame I guess. The extra bedding is updated, it starts at 0 and goes to 1, 2, et cetera. Until it is at 40ADP, every single time, our column will be updated with this new bedding. If we run this, we should be able to see that now this expands with a nice animation. There is one small last thing we can do here, we can actually define capability medication spec here. You can quickly customize the default animation spec which in our app we can see by pressing show more, show less. You see that is now nicely animated. You can also use capability medication spec here. For example, you can use the between, going linearly from one to the next. We can set how long we want this to take, for example. We can say the duration is 2,000 mill seconds, this will take 2 seconds to run. This way, there is different types of mentioned specs to work with, you can create easily like springs or bounces, whatever, however you want to animate your things. It is a low animation. >> FLORINA MUNTENESCU: Honest ly, seeing that you have four lines of code and you have the animation and customized it, yeah, I really like it. I can be really lazy. Cool. Do we have anything more to show for automations? >> JOLANDA VERHOEF: I think this is it. >> FLORINA MUNTENESCU: Cool. However, we have to wrap it up. If you switch back to the code lab, we see that we have one more section that we didn't get to. A few final touches. We promise, starting -- this is easy, we can't just cover it in 3 minutes. If you want to learn more about compose, we have a compose pathway, do we have the -- >> JOLANDA VERHOEF: Yes. It is in the code lab actually. >> FLORINA MUNTENESCU: Perfec t. Great. Yeah. Check out the compose pathway, we have a lot of resources for you. To get started with compose. Similarly, we have a lot of documentation on our developer online and we know you want to try things more, we have another compose, migrating to compose code along tomorrow. Also tomorrow we have an ask Android focused on compose and material use. Bring all of your compose questions to that. I think this is it for now. Thank you, everyone, for watching, for following along. Thank you. >> JOLANDA VERHOEF: Good-bye! >> FLORINA MUNTENESCU: Bye! we will want to bring theoday reactive programming concept close to development. We will see how to work with coding types with modeling streams of data, and there is a particular UI life cycle that we have seen, how to optimize the flows for things like sending the app and as with all good stories, we have to test that everything works as expected. >> Every Android app has to send one way or another, there is a million different use cases. Loading user name from a user base, fetching a document from a server, authenticating a user, in this talk, we'll look at how we can load the data in a flow, transform it, expose it to a view so that it is displayed. To help me explain why we use flow, here is Pancho who live owns a mountain, when he wants fresh water from a lake, they do what anyone does, they grab a bucket, walk up to the lake, down again. Sometimes p the lake is dry, they waste time as they have to find water elsewhere. After doing this multiple times, they realize it is much better to create some kind of infrastructure. The next time they walk up to the lake, they install pipes, if they need more water, the lake is not try dry, they open the tap. Once you know how to install the pipes, it is easy to be fancy and have multiple forms of data. So in capability droid app, you take the easy path, request data every time you need it. For example, when the view starts, you request the data to a model which in turn requests the data to the data layer and then everything happens in the other direction. You can do this easily with a suspend function. However, after doing that for a while, developers tend to realize investing in some infrastructure really pays off. Instead of requesting the data, we observe it. Observing the data is like installing the tubes for water, when in place, any update to the source of data flows down automatically, you don't have to walk to the lake hi more. The system that uses these pattern, they're reactive, because observers react automatically to changes in the things being observed. Another important design choice is to keep dataflowing in one direction as this is less prone to errors and easier to manage. In this example, the manager tells the database that the user logged in, that this one in turn has to tell the remote data source to lower the different set of items, and you will of this while telling the view to show a loading spinner while grabbing new data. This is doable and prone to bugs. A better way to do this, it is to let the dataflow in just one direction and create some infrastructure, some tubes to combine and transform the streams of data. If something changes, it requires modifications, such as when the user logs out, the tubes can be reinstalled. As you can imagine, we need sophisticated tools to do all of the transformations, and in this talk, we'll use Kotlin flow for it. It is stream builderroller out out there but it is well supported. >> MANUEL VICENTE VIVO: What we have used to far is modeled in concrete type Kotlin flow, this is part of the library. Instead of water, flows can be typed as T, user data or UI state. There is some terminology that will be used during the talk that's important to define. The producer emits data in the flow, the consumer collects from the flow. In Android, the data source, the repository, it is typically a producer of application data that has been UI as the consumer that automatically displays the data on screen. Let's start with how flows are created. For that, let's take a walk to the lake. Most of the time, you don't need to create a flow yourself. The libraries you depend on in the data sources, they're already integrated with flows. This is the case of popular libraries such as data store, retrofit, room, WorkManager. They are like a water pipe. They provide data using flows. You plug into a pipe without knowing how the data is being produced. Taking room as an example, you get notified of the changes in the database by exposing a flow of type X. The room library acts as a producer and emits the content of the query every time that an update happens. If you really need to create a flow yourself, there are different alternatives that you can choose. One of the options, it is the flow builder. Imagine that we're in a user message data source and you want to check for messages and resolve and from the app. We can expose the user messages as a flow of type list of messages, to create the flow, we use the flow builder. The flow builder is a parameter which means that it can cause suspend functions rain this is because of the flow, it is executed in the context, and inside of that, we have the repeating of the logic periodically. First, we fetch the messages from the API and then we go to the flow using the emit suspend function. This is a step to suspend the current space until the receiver has the item. We then suspend that for some time n a flow, operations are executed subsequently in the same way. Due to the flow, this is infin knitly fetching the latest models until the observer goes away and stops checking items. Also, the suspend block going to the flow builder is often called producer block. Android can modify this stream of data with the requirements of the following layer. To transform flow, you can use intermediate operators. If we consider the latest messages stream as the flow starting point, we can use the map operator to transform the data to a different type. For example, inside of the map lander, we're transforming the messages coming from the data source, to the message, UI model, it is a better abstraction for this layer of the app. Each operator creates a new flow that in its data according to its functionality. We can also enter the stream to the data throw for those messages that contain important modifications. Now, how can we handle errors that are part of this? The operator catches exceptions that could happen while processing items in the upstream flow. The upstream flow refers to the flow produced by the producer block and the operators called before the current one. Similarly, we can refer to the everything that happens after the current operator as the downstream flow. This is the exception if needed and create barriers. For example, this is the argument exceptions, and it alerts if there is an exception that occurs. We have seen how streams are produced that the point and how they can be modified. It is time to learn about how to collect them. Collecting flows, it usually happens from the UI layer as it is where we want to display the data on the screen. In our example, we want to display the latest messages so that the Pancho can keep up with what's going on. We have to use the terminal operator to start listening for values. To get all of the values in the stream as they're limited, use collect. Collect takes a function as a parameter, it is on the renewable value, as it is a suspend function, it needs to be executed with this. When you apply a terminal operator, the flow is only starting emitting values, on the contrary, intermediate operators set up the chain of operation, the data collection when an item is going to the flow. When collect is using the user message, the new flow, pipe, they'll be created and the producer block will start refreshing the messages from the API at its own interval. We refer to this type of flow as cold flows as they're created only with the data when being observed. Let's say how to optimally collect flows from the Android UI. There are many things to consider. The first one, about not wasting resources when in the background and the second one, it is about configuration chains. Let's imagine we're in the activity and we want to display the list of messages on the screen. For how long should we be collecting from the flow? The UI should be a good citizen and stop collecting from the flow when the UI is not displayed on the screen. Back to the water analogy, Pancho should close the tap when brushing the teeth or going to a nap, not wasting water. Similarly, the UI should not be collecting from flows if the information is not going to be displayed on the screen. Through this, there are different alternatives, and all are aware of the UI life cycle. You can use live data, life cycle specific APIs, such as repeat on life cycle and flow with life cycle. The dataflow operator converts the flow to live data and selves items only when the UI is visible on the screen. This conversion, it is something that we can do in the view model class. In the UI, we consume the live data as this one. This is because it is adding a different technology in this that should not be held. Repeating life cycle, it is the recommended way to collect flows from the UI layer. Preet on life cycle is a suspend function at a takes a life cycle state as a parameter. This API, it is life cycle aware as it automatically launches a new team when the life cycle reaches that state. Then, when the life cycle falls below that state, the ongoing counsel, inside of that block, we can call collect as we're in the context of that. As repeat on life cycle is suspend function, it also needs to be called accordingly. As you have the activity, you use life cycle scope to start one. As you can see, the best practice is to call this function when the life cycle is initialized. For example, creating this activity. Repeat on life cycle, we start the behavior and it takes into account the UI life cycle automatically for you. Something important to notice, it is that the repeat on life cycle, it won't resume executing until the life cycle is destroyed. So if you need to collect from multiple flow, you create multiple ways to use launch the repeat on life cycle block. You can also use the flow with life cycle operator instead of repeat on life cycle when you have only one flow to collect. This API in its items, it has the underlying producer when the life cycle moves in and out of the target state. To show how this work, visually, let's take you through the activity life cycle when it is first created and then sent to the background because the user pressed the home button, making the activity stop the signal and then opening the item up again when the item is cold. When you call repeat on life cycle with this state, the UI pros the flow emissions while it is visible on the screen. And the collection is when the app is in the background. Repeat on life cycle, flow, it is life cycle, it is new APIs added in the stable, 2.4 version of the life cycle run time KPX library, they're new and you will create the flows in a different way. For example, you would be checking directly from one launched by life cycle scope, and while this may seem okay to you, collecting flows in this way is not always safe. This collects from the flow and updates the UI elements even if the app is in the pipeline. In fact, this is not the only case. Other solutions, like the life cycle, scope, launched API family, it suffers from similar probes. You don't like the water being wasted, do you, you should not collect from the flow if those items, if they're not displayed on the screen. If you collect directly from life cycle scope at launch, the activity keeps receiving flow updates while in the background. That can be both wasteful and dangerous, as for example, showing dialogues in the background, they can make your application crash. To solve this issue, you can manually start collecting and stop collecting while in stop. While that's okay, you use the repeat life cycle, it removes all of that code. If we look at launch when starting as an alternative, it is better than life cycle scope at launch. It suspends the flow of collection while the app is in the background. However, this solution, it keeps the flow producer active, potentially even the items in the background that can't fill the memory with items that will be displayed on the screen. As the UI doesn't really know how the flow producer is implemented, it is always better to play safe and use repeat on life cycle or flow with life cycle to avoid collecting items and keeping the flow producer active when the UI is in the background. If this optimizes flow collection when the app goes to the background, we have some tips for when the app goes through the configuration changes. >> When you expose the flow to a view, you have to take into account the data passing between two elements that have different life cycles. Not any life cycle. The life cycle of activities and fragments that are tricky. As a crucial example, remember that when a device is rotated, receives second configuration change, all activities might be restarted but a few model may not. You can't just expose any flow, the call flow like this one. A call flow restarts every time collected for the first time. So the repository, it would be called again after a rotation. What we need, it is some kind of a buffer. Something that can hold data and share it between multiple collector, no matter how many times they are recreated. State flow was created for exactly that. A state flow is water tank in our lake analogy. It holds the data even if there are no collectors. You can collect multiple things from it, it is safe to use with activities or fragments. You could use the amusable version of state flow and update the value whenever you want. For example, from the quarantine like here. That's not really reactive, is it? You should improve the game. Instead, you can convert any flow to state flow, if you do that, the state flow receives all of the updates from the upstream flows and stores the latest value. In turn, you have the 0 or more collector, this is perfect for the models. There are more types of flow, but this is what we recommend because we can optimize state flow very precisely. To convert the flow to state flow, you use the state in operator on it. It takes three parameters. Initial value, because the state flow always needs to have a value. The scope, which controls when the share something started. We can use the view model scope for this. Started up, the interesting one, we're going to get to what that is while subscribe 5,000 means and first let's look at two scenarios. The first scenario, it is a rotation, where the activity, which is the collector of the flow is destroyed for a short period of time and then recreated. The second scenario is the navigation to home where the app is put in the background. In the rotation scenario, we don't want to restart any flows to make the transition as fast as possible. In navigation to home, however, we want to stop all flows to save budgetary and other resources. How do we detect which one is which? We do that with a time lap. When the state flow stops being collected, we don't immediately stop all of the upstream flows, instead we wait for some time, 5 seconds, if the flow is collected before the timeout, no upstream flows are canceled. That's exactly what was subscribed. In this diagram, we show what happens when the app goes to the background. Before the home button is pressed, the view is receiving updates, the state flow has its upstream flows producing normally. Now, when the view stops the collection ends immediately. However, the state flow, because of how we configured it, it takes five seconds to stop the upstream flows. Now, the timeout passes, upstream flows are canceled. Only when the user opens the app again, if that ever happens, the upstream flows are automatically restarted. In the rotation scenario, however, the view is to stop for a very short time, less than 5 seconds anyway. The state flow never gets through start and it keeps all upstream flows active. Acting as though nothing happened and making the rotation instant to the user. So, in summary, we recommend that you use state flow to expose your flows from the model or keep using as like data doing the exact same thing. If you want to learn more about this, check out the resources at the end. Now you may wonder, how do I test this? Well testing a flow can get tricky because you're dealing with streams of data. So there are a couple of tricks to use. First, there are two scenarios. In the first one, the unit under test, whatever you're testing, it is receiving a flow. The easy way to test this, it is to replace the dependency with a fake producer, you use this fake repository in the example to whatever you need for the different test cases. For example, with a simple call flow. The test itself, it makes a session on the output of the subject on the test which is a flow or something else. Secondly, if the unit under test is exposing a flow, that value or stream of values is what you want to verify, you have multiple ways to collect it. You can call the first method on the flow, and this is going to collect until it receives the first item and then stop collecting, and also you can use operators such as take 5 and call the two terminal operators to collect the exact five messages that are useful. Hopefully in this talk you learned why the reactive architecture is an investment and how to build an infrastructure with flow. If you are inspired, we have a ton of content around there, a guide covering the basics and blog posts with we do deep dives. If you want to see it in context, check out the Google IO app which we updated earlier this year to include the flows everywhere. Thank you. the studio team and I'meer on Joaned by Scott, an engineer on the Android -- joined by Scott, an engineer on the Android team. We will talk about benefiting from the Gradle 7.0 to improve your build. We'll talk about the performance improvements and steps required to benefit from Gradle configuration and to you to extend the AGP with the APIs we added in 7.0, we'll start with the performance improvements. Kotlin symbol processing brings first class support for annotation processing for Kotlin and replacing KPT, using KSP processers to run two times faster compared to the KPT. They are all popular annotation processers that offer the KSP compatible versions, the room about more coming, if all of the processers you use to support this make sure to migrate from Gradle plug in to KSP plug in, to learn more, visit. With our classes enabled, the resources are declared in the product itself and not from the dependencies. It reduces the size of the class for the project. The scenario is where this is very helpful, it is when you add a new resource in a round time redundancy, we avoid the downstream modules and this scenario improves by 40% with the R classes enabled. With clean builds we see the 5 to 10% improvement. You can add this flag in the Gradle property file and we have updated that with factory help in Arctic Fox and you run the refactor R classes which adds the flag to the built and modified sources if needed. The libraries are already using this feature and the AR staged it, they do not contain the resources from dependencies any more. There have been several recent performance improvement, since 7.0, the tasks are up to date and the analysis tasks can run in parallel per module when check dependencies are set to true. Since 7.1 Alpha 13, the analysis task is compatible with the Gradle built cache, to demonstrate the improvement, we have the 15 modules, and we have checked dependencies at true and Gradle caching enabled. We see a two times improvement from 4.2 with a more dramatic improvement in AGP7.1 with all of the analysis have cached. You may see improvements but there are simple things to try to Firth improve the performance. To benefit from the analysis task being cachable, you have to have this cache enabled. Enable that with this added, see this link for caveats to consider when enabling the Gradle built cache. Another action item, to try the performance tuning in the user guy, making sure that you have given them enough memory. The final action item, its to try setting check dependencies to true in the application option block. This will not make it run faster but allow it to catch more issues and will produce a single entry point for the entire project. Now let's talk about the configuration. At the beginning of every built Gradle creates a test graph used to execute the build operations, it is the configuration phase and it takes from a couple of seconds to tens of seconds. Configuration cache is a feature that allows the caching of the configuration phase of the build and reusing that in subsequent builds, when there is a configuration cache, all tasks run in parallel and dependency resolution results are cached resulting in further improvements, note this is different from the Gradle built cache for task output. The setup, fully defines the phase of the configuration, they capture the components. This together with the task that you requested to run, uniquely determines the tasks you will execute in the build. To imstraight the improvements this provide, let's look at a Gradle build project with the latest version of Kotlin, others, you see the clean build, incremental build with a public method and modified method body. In all scenario, we see 20% build speed improvement. Let's take a closer look at how configuration cache works. Before the task graph is computed, we are in the configuration phase. We're using the Gradle providing are global outputs, the task container, configuration container to create tasks with the inputs and outputs. As in this example, where we register the task, you configure it, in this script we see multiple usages of the global objects like project of tasks and proj project.configurations, that's fine as we're still done figuring the build. When configured, Gradle computes the final graph, it stores this graph and sterilizes the task state and save it is in cache, all inputs need to be of specific Gradle types or sterilizable. Finally, when there is a configuration cache, the stored configuration entry are used to create instances, only state that's been previously sterilized could be referenced in the newly substantial rated tasks and no references to the global state are allowed. To check if the build is compatible with configuration cache, we have the build analyzer check. After that, build the panel and you will see how long the configuration takes n this example, it is 9.8 seconds. Click the optimize this link and it will take you to another panel with more detailed information. In this particular example, all plug ins are compatible and clicking, trying configuration cache in a build starts the flow and was updated and a flag to consider the configuration ca ce was add the. You have the plug ins to the newer version that's compatible, in case the build is incompatible, build will fail, and debugging the information will be provided. Let's take a look at the incompatible example. Here we have a task that computes current and raises that to an output file, it runs the command, captures the output and rides the value to a file. Running the task with configuration cache enabled shows two problems. When the build is incompatible with configuration cache, it lessen generate a HTML file with a list of issues. If you open that report, you see the traces pointing to the issue. They point to lines 5 and 11 in the build script. Going back to the task source, we see that we have project access in the function that returns the file output location. That's the first reported issue. The second issue, it is using the project in the task action. This is the global state we cannot access with configuration cache enabled. Let's see how to fix this. We can store pieces of information we need in task properties and they'll be stored in the configuration cache and we look at the services to look at the external process, this is the version that's compatible, we capture the location in a property that we configure in the task registration and the service, it is used to launch the command. This is how we can use the task in our build, the output location is set during task registration as a plus, Gradle is live and any changes to the project build directly is automatically reflected in the output location of the task. To learn more about configuration cache check out Gradle documentation in this article that describes how to migrate the build. >> Thank you. Now we'll take a look at extending the Gradle plug in. Many of you have probably wanted the build to do something that was not supported out of the box. In this section, we'll discuss the new variant and artifact API we added to help you modify the build safely, before diving into the variant artifact APIs, let's clarify what variant and artifact mean. Build types and product flavors should be familiar concepts to you from the files. AGP creates products from these and for each variant, AGP produces variant specific tasks. The outputs of the task, they're registered as artifacts of the corresponding variant. Most of these intermediate artifacts are private, some are now public. Previous versions of AGP allowed API access to the tasks. This was brittle because the tasks, they're an implementation detail subject to change, 7.0 alloys access to the variant object and some intermediate artifacts it allow users to influence the built behavior without touching the tasks. Now we'll walk through the details of an example project using the new variant and artifact APIs to modify an intermediate artifact, how to custom an element to the DSL and add a custom property to the variant API. We'll work in the build source directory to create a Gradle plug in to accomplish these goals. The source code for the project is compatible with AGP77.1 beta 1 and available at this link. First we focus on modifying and intermediate artifact. Specifically, we'll add an extra asset to the APK by modifying the assets art affect. To achieve this, we will first need a custom task like the add asset task shown here. This task has a single string input and a single directory property output. The task writes the input string to a file in the output directory using the variant and artifact APIs we register an instance of the add asset task and wire it to the assets artifact. That's all that's required to get the extra asset in the APK. This block of code is the key. It adds the tasks output directory to the collection of asset directories and wires the task dependencies properly. As it is written here, we're hard coding the content of the extra asset. In later slides we'll change this behavior it allow us to set this content per variant. AGP allows users to interact with several different artifact, some shown here. We have appended to, this and AGP supports interacting with several other ways. For example, you may want to verify the contents of one of the artifacts. You can do that by getting the artifact. Shown here for the AAR artifact. For more ideas, examples of how to interact with these intermediate artifacts please check out the new APIs and the Android Gradle plug in blog post on medium. Back to our project, now we want to add DSL to allow us to set the content of the asset. We have added the ability to add DSL for a custom plug in to the existing DSL. We use this feature to allow setting the content of Pratt asset per built type n shows how to use the module file. Notice how this blends in with AGPs existing DSL, to extend this, we first need to create a simple interface like the one shown here. We can name this interface whatever we like. We'll call it toy extension. When we have the interface, we can add it to AGP built type with the code shown here. We can extend that product delivers in a similar way but not in this example. When we have added the custom DSL, we want to get the value in the on variance block so that we can set the task input with the value. First, we look up the custom toy extension we added using the variance built type, next the value from the DSL or use the default value if it hasn't been set in the DSL. We register our task and set its content input with the value from the custom DSL. Now the extra asset will get its content from our custom DSL. Similar to extending the DSL, you can also now extend the variant API by adding your own Gradle property or provider to AGP variant object. Why do you want to do this? Extending the variant API offers advantages over just extending the DSL. Unlike DSL values, custom variant properties can be set with the output of a task with all dependencies handled automatically by Gradle. Second, with a custom variant property, it is easy to set it with a unique value per variant. Third, compared to custom DSL, custom variant properties allow for easier, more robust interaction was other plug ins. Similar to extending the DSL to extend the variant API we first need to create a simple interface like the one shown here. We call this one toy variant extension. Comparing it with the toy extension, you notice that we're using a provider instead of a string. This is intentional. It is the convention we use internally in AGP. Using a provider allows the value to be set using the output of a task. It also removes the complexity of having to consider plug in ordering. Other plug ins can set the value whether they're applied before or after the toy plug in. This slide shows how we will be able to use our custom variant API in a module gradual file. The usage is not as clean as the custom DSL, we see that setting the unique value per variant is easier with custom variant API compared to custom DSL. Implementing this variant API extension in the toy plug in will require code like this in the before variant block. In this block, we're creating an instance of the toy variant extension. Setting the provider initially with the value from our toy DSL and registering it with AGPs variant object. This must be done in the before variant block. Not the on variance block. We cannot register variant extensions in the on variance block. They must be registered in the before variance block in order to be available to any plug in that may access them on the on variance block. Similar to a previous slide, we look up the value from the custom toy DSL. We can do this safely in the before variance block because the DSL is guaranteed to be finalized and blocked before the call back is called. We initially set the property with the DSL value or the default value if it is unset in the DSL. This is an important point because it is the same convention we use internally in AGP. Finally, we add our custom toy variant extension to the variant object via the register extension method. After that work in the before variant block we don't have much to do in the on variant block to set the task input with the custom variant property. This is a good illustration of why adding such a custom variant property is a good idea if you have multiple plug ins that need to interact in a variant specific way. If a gradual plug in wants to set the property or use it for one of its tasks, then it would only need to do something similar to what's shown in the on variance block. To learn more on extending AGP, check out the new post on the subject. Also please take a look at the continually updated AGP cookbook to get more examples. There are more build and snyc improvement on the way. Gradle project isolation is a feature that builds on top of configuration cache to provide more build speed and sync time improvements. Each project is configured in isolation. No cross project references are allowed. This allows Gradle to cache sync outputs per project and if the file changes, only the impacted project is reconfigured. The feature is currently under development and you can try it out with this flag using Gradle 7.2. Please continue following Gradle release notes and we have a goal of supporting all ink mental scenario, for example, Android resource modifications, building cache support, other projects. Thanks to you, the developers for all of your support. Thank you for trying our preview versions and for filing issues on the issue tracker. Please keep up the great work and let us know how we can help. Thank you. >> Lucy: Hey. Today I'm going to walk you through all of the new features our teams have built to help you power your growth on Play as well as highlighting important dates and deadlines for you to be aware of. We'll talk about improvements for trust and safety, tools to boost your quality and improve monetization, updates for games and a new store listing certificate course. So let's get started. Google Play is committed to providing a safe, secure platform that protects both you, app and game businesses, and the billions of people who trust Google play to discover the latest Android content. Earlier this year we shared details about the upcoming data safety section in the Play store which will let users know the type of data the app collects and stores and how that data is used. By giving you a way to showcase your approach to previously insecurity we're not only building user trust but helpaling people to make informed decisions on the apps they install and use, users will see the new data safety section in play store starting in February. We know some of you need more time to assess the apps and to coordinate with multiple teams, we're giving you until April before the apps must have this section completed and approved. We encourage you to get started early and submit before the April deadline, for information, including guidance on how to fill out the form, you can read our help center article or watch our session get prepared for the data safety section. You can find the link for the section in the video description below. The new Play integrity API protects apps and games from abuse and attacks. It helps you to detect risky, untrustworthy interactions so that the back end server can decide whether to trust the interaction. At launch, at P, I sends three signals, is this the unmodified binary, a genuine play in stall and a genuine device running Google Play services. If any of the signals are not what you expect, the server can decide what the app should do next to reduce the risk such as asking the user for verification or reducing access to functionality. The play integrity API will rollout to everyone in the next few months, we'll publish a preview of the integration guide very soon and the URL shown on the screen, along with the information about migrating to the new API from safety net device section and play licensing. To learn more, watch our session play integrity API, it is linked in the video description. Another major contributor to your app success in Google Play is quality. In fact, nearly 3 quarters of five star reviews on Google play mention the quality of the app experience in terms of performance, design, usability. Because quality is so important, we constantly are making changes to serve the higher quality apps in the store. To make the most out of Google play, you have to invest in the quality of the app, but what's that quality really mean? App quality includes the overall experience of the app, the technical quality, the quality of your listing on Google play. So to help you maximize your success, we have released several updates to help you improve the performance of the app. Let's start with the technical quality. First, we are making it easy for to you spot new issues with improvements to the Android vitals. The most recent data, it is now more visible to help you quickly identify the source of the issue. These improvements were made possible by some new capabilities available in Android 10. Look out for new features soon. We're also making some changes to ratings and reviews to make them more indicative of the experience that each user can expect. Starting in November, users on phones will start to see ratings specific to their registered country, then in early 2022 user also see the ratings specific to the device that they're still on, including form factors such as tablets, Chromebook, wearables. You can preview your location specific and device specific ratings in Play council today, we encourage you to check them out so that you can make any app quality improvements before the new ratings are shown to Play store users. When we look at quality, we also considered the reach of your high quality experience. That's why we recently launched a new tooling consult called reaching devices to help you to understand which features or fixes would help you to reach the most users on Google play. By understanding the user distribution you can make more informed decisions about which specs to build for, where to launch, what to test to make the biggest impact. Stay tuned for more in this space in the next year. Of course, one of the biggest aspects of growing your business on Google Play, it is earning money from the Apple game. This year we have made changes to help you monetize your apps and reinvest in your business offering you more options and flexibility. Earlier this year, we announce that the service fee for the first 1 million in earnings is now 15%. Today, more than 99% of all developers are eligible for a service fee of 15% or less. If you haven't already enrolled, please do so at the link shown on the screen. The 15% rate is effective from the day that you enroll. We're also constantly adding new features to the billing library, including new ways for users to pay, subscription promotion capabilities, purchase attribution for games and improvements to purchase reliability and security. Today I'm excited to announce one of the new features coming in app messaging. Today, subscription users that go in to payment decline often are not aware of it or experience too much friction to fix their payment. The best place for users to learn about their payment decline and fix it, it is in the app itself. Too often we hear from developers that it is a lot of work to determine the users' payment state and show the right messaging. That's why we're announcing a new API that can detect whether a user is in payment decline and show a helpful message right in your app. This allows users to immediately fix the payment without leaving the to go to the Play store. Best of all, the integration is super easy, just a few lines of code. We have already seen positive results from our early access partners, and on average, developers saw a 9ed% improvement on the subscription recovery for users that saw the message. In app message something available in the next billing library release. Stay tuned for more information. In order to help you benefit from the features, keeping the infrastructure modern, up to date, we have established a yearly cadence for updating to the minimum library version. As a reminder, all updates to existing at that point apps must use billing library 3 or newer by November 1st, after November 1st, you won't be able to public apps using older integrations. IDL, building library version 1, building library version 2. Apps already in the play store will continue to be downloaded and processed in app purchases, however, any subsequent app releases will require billing library version 3 or newer. Updating to billing library version 3 or newer, it is simple and requires just a few updates to the code. More information about the changes can be found in the release notes in our developer documentation. We have made improvements for our game developers. Now in early access the updated sign in API for play game services drastically sympathizes the sign in implementation, in fact, it is a single line of code. It gives you a convenient way to sign in the players and to save the game progression. You can then retrieve, play game data to allow returning players to continue playing from the last save point from any device. You can integrate popular gaming features such as achievements and leader boards. We have also simplified the set up for users, combining the Google Play game install and profile creation into one step. This allows users to get back to the game more quickly, even if they don't have Play games installed. We're streamlining the process of opting in to auto sign in for a smoother experience for returning users, that's not all. Meetings have the Google Play game app installed, it is creating friction for some users. So starting in 2022 Play game services will no longer require installation. This change will allow 2 billion users to sign in to the Play game services enabled game was a zero touch experience. Stay tuned for more details. In the meantime, you can express the interest in the Play gamives early access program on the developer site. Last but not least, I'm pleased to announce the launch of the Google Play store listing certificate, this new program is designed to help app marketers demonstrate the proficiency and skills in placing the best practices, to get certified, you can take our online training at Google play academy and learn best practices to help you best tell your Ap story. You will drive growth through high quality, policy clients store listing, after the training, take the exam to get an industry recognized certificate. You can make yourself stand out, whether it is in the organization or in the industry. We hope you take advantage of all of these tools, features, programs to grow your businesses on Google Play. Please continue sharing your feedback so that we can continue to build the tools you need to power your growth on Play. Thank you for being part of the Google Play community. manager for wear OS, today we're going to talk to you about the new developer preview of compose for wear OS, specifically, we'll walk through what's similar, different, what's new in this version of compose so you can quickly develop your own beautiful apps with less code. There are many reasons why compose for wear OS will be helpful. The components are compliant with material guidelines out of the box, meaning you can more easily follow the design guidelines. Compose for wear OS is currently in Alpha, releasing a number of updates since we teased it at IO. We're now ready for a developer preview. We want to incorporate your feedback in the early iterations of the libraries before the release. We expect you to have knowledge about compose going through the talk, and don't worry if you don't understand everything. We'll have resources at the end to help you learn at your own pace. Before we dive into compose itself, let's talk at a higher level about the differences between wear OS and Android mobile development. For any of you not familiar with wear OS. As a recap, we launched a new version of the platform with some major improvement of the wear OS experience. That didn't change the fact that the new version of wear OS is based on Android. As before, as optimized for the wrist. A benefit of compose for mobile is that it works across many versions and API levels of Android. Similarly, compose for wear OS will work on 3, the level 30 and on the wear OS 2 watches out there. And just like mobile, compose for wear OS is part of the jetpack library and just like the other libraries you use, it helps you to write better code. Let's look a little higher at some of the fundamentals of wear OS app architecture. You may not realize it, when you are developing for mobile, you are actually targeting more than one surface. First, the app surface, in the old world it has UI powered by fragments activities and views. In the new world of compose, the UIs are powered by composables, and you know all of that and are used to that. You are also developing for another surface, notifications. That's going to be when you want to alert the user of some important information outside of your app or let them continue something that may have started in your app like tracking the run, playing music. Finally, if you are using widgets, that's another surface where you can provide information to users. Wear OS is similarly comprised of multiple surfaces you want to target when creating a full fledged wear OS app experience. First is the overlay. It is basically just like the app on mobile. Previously composed of activities, view, fragments, now by composables, it is well suited for longer, more complex interactions, and notifications also follows the same principles of mobile development, then there are two new surfaces, complication, providing predictable, glancable access to information, directly from the watch face, and when tapped, complications usually direct to the corresponding app experience. However, they can perform the self-condition takened action like a water complication, changing the number of glasses you had during the day. Finally, tiles give users the fast access to information and actions with more space to display content. They're reachable by swiping in either direction from the watch face. For this session, we are focusing on overlays. The phone equivalent of an app and this is where ail of the use reviews or composables will live. We'll quickly demo a number of wear composables to give you an idea of how they work and similar to mobile before diving into the more complex composables. Before we cover any, we have to make sure we have the right dependency, and the dependency high school be a little bit different from mobile composed. You look at mobile first. On mobile, you have the main set of dependencies, the material, foundation, UI, run time, compiler, and optionally, you have navigation and animation. What about wear? First, let's talk about what's the same. On wear, you can use the same UI dependency as in mobile and the run time compiler and animation dependencies are the same. A lot of the other stuff is the same too. The tools and the compose philosophy like data down, events up. Okay. So what's different? First replace material with the wear compose material, it is possible to use the mobile material, it is not optimized for wear and wear's unique requirements. We recommend that you replace it with the wear equivalent. The other material dependencies outside of that can still be used. For example, you use material ripple and material icons extended, next, include the wear foundation dependency, this ise additive, you use this with a mobile dependency if you want to. Finally, if you are using navigation, replace it with the wear navigation equivalent. For the same reasons that you would with material. It is optimized for the watch. Now we'll walk through material, where many new composables can be found. >> I'm Jeremy walker, I'm a developer relation engineer at Google. The compose wear OS material library offers many composables that you have grown used to on mobile but optimized for the watch. As with mobile, you can override the material theme and customize the colors, typographies and the shapes. Buttons are complex elements to allow users to take choices and action was a single tab. Here are some examples. They look different from the mobile equivalent, the code is the same. Let's look. We have the button, the composable, just like as before. Next you have the parameter, you're used to the modifier. That's on everything. You have unclick, same, enabled. This case, enabled state. All right. Let's say you want to add an app icon. This is just the same as it was before on mobile. You had the content de scripter and the modifier. The code, it is exactly the same as you do on mobile. Let's see the results. Okay. Here you have a nice button. Now you use the same code, it is optimized for wear OS. With a small amount of edits, you vastly change what it looks like as well. Here are other examples. Let's jump into another one. Cards take content and actions about a single subject and have a lot of flexibility as you see from the examples here. On the left we have an icon, tags, you have the text, on the right, we have an image as the background. Here you have the two main carts, the app cart, you have the title card, focused on text, we'll focus on the app card. In this case, I'm just setting an image, I'll set some text, I'll set a text composable on all of these in order -- I'm not going through them all. You can see pretty straightforward, you have the click, finally, I'm going to set the body, in this case, I set a column, the text as well. I could add another text in I want to, I'm just using one here. Again, this code, it is similar, let's look at what it looks like. Will is a nice card optimized for wear OS and the same thing here, you have the slight modifications and you have the different beautiful looking cards. All right. Chips. Chips are actually specified in the material guidelines and there is not one in the mobile material library. They are meant for quick one tap actions, they make especially good sense for the wear device and limited screen real estate. Here is a couple of variations of chips to give you an idea of what to create and give you code. The chip, it is straightforward, nothing out of the ordinary, the parameter, those are going to be similar, this is stuff that you usually set on other things. I'm going to just set a label, we have one minute yoga, about right for me. We'll set an icon. Pretty straightforward stuff. This is what it looks like. Again, with a little bit of variation, you make all sorts of different chips. Let's have a look at another one. This is toggle chip, this is similar to chips, it allows the user to use a radio button, a toggle, a chip box, like on the left, you disable the sound by one tap and you turn it back on. On the right, we have the split toggle chips, it offers two different toggle chip, one on the right, you turn it off, on the left, it taps into the app, you want to edit the alarm here. On the right, you turn it off. Let's look at the code. You toggle chip, straightforward. You set the parameters. This is just going to be similar to what you're used to with the other composables that I have shown. I'm just going to set the label for sound, this turns on and off sound. We see what that looks like. We have the nice sound, toggle chip here. You turn off the sound, again, with a little bit of variation, you have all of these options. Okay. At this point, you probably have a pattern. Many composables, they're the same as what you have already used and in the new months, they're so familiar, that they are almost the same. In other words, most of the work you have done to learn compose, you now have it on wear OS, it is great. Compose is fun, right. Okay. Let's look at another one I really like. Curve text, it is optimized for the round screen, obviously it is important for a round device. Time text, it is another option which basically is under the hood and uses curve text. It takes care of all of the time for you. You do not have to mess with any time related classes which makes me super happy. Actually our material guideline calls it you keep the time at the top of your screen within the app or overlay experience. If you are actually using the wear scaffold, then you take care that have for you. I will talk about that later. Let's have a look at it. So first I'm going to actually create text that I set before my time. I do that first. Next I create the time text composable, I want to specify the leading curved content, and what that means, it is this is the text that will show before the time. Before it is curved, this will show only for curved around devices. In this case, I'm using under the hood, a basic curve text and I set the time. Next, I do a linear content, that's for the scare or rectangular device, I want to use the regular text there and I want that to be in front. There are other options to put the text behind, you add a separator if you want. You keep it simple, it is on the front here. This is what you get. You have ETA, that's the text I created, the time, the best part, I didn't have to mess with any time classes. If this was on a square device, then it shows up nicely on a square device as well. All right. Let's talk about lists. So lists. Let's have the continues vertical set of elements, you know of this, everybody uses lists everywhere. It is a bit different on wear OS. On the top and bottom of the screen, there is less space. The material design introduction scaling and transparency, with the new scaling lazy column, this helps you view the lists on a small space, let's look at that. This is an example to show exactly what I'm talking about. You see the element as it comes up, it is bigger, it is more opaque and it goes away, it gets smaller, it kind of disappears a little bit. That's what scaling lazy column does for you. Here is an actual app where you can actually see it, same thing. It scales up, disappears. It scales down, disappears as well. It is nice and helps in the readability. All right. So scaling lazy column. It should be the default for any app on wear OS. Obviously, it gives the scaling and transparency affect we talked about, it handle as large number of items. You're guessing by the name scaling, lazy column, it was built with lazy column and you would be right. You have the advantages of lazy column, for instance, when you have a long list like what we see on the screen there, you only can view the small portion of it. Lazy column, it will do the optimizations and only compose what's needed on the screen at the time. You get all of that for free. The nice scaling and transparency features. All right. Let's look at the code. So you are used to setting state anyway for the lazy columns. Same thing here. You use the different name. Remember scaling, lazy list state. That's the mouthful. It explains exactly what it is pretty well. Next you create a lacey column like a lazy column and you set the parameters. These are the same, modifiers, vertical arrangement, the use of the state. After that, you set the content, this is exactly the same. Items are supported in item. So whatever you want to do here. That will give you something like this. With no extra work. It is great. Now we want to talk about something else that you're familiar with, box. As a reminder, a box, it is basically a container for the screen, you can use it on mobile, and we have our own, and it is called swipe to dismiss box. This is going to be for the layout. You probably are guessing for the name, swipe to dismiss, this means swipe to dismiss. Pretty straightforward. On wear, a main gesture is swiping, that goes back, as if it is the back button. In this case, this is a support out of the box. Let's look at the code. What's different from box and mobile, you have the state, so you have the remember swipe to remember that box state, you create the composable, and you pass in the state. You get a background, what that means, it is in the process of swiping away. You can actually render different things based on that. In our days, we render a different color so that you can see it. If you are not using a navigation, you probably want to show the screen, it was before the current one, slightly back. Then in this case, I'm setting a column with text, I could add more, we'll keep it simple. This is what it looks like. Also there is a bunch of other options to do. We have launch, defect, you will want to use the navigation and if you're doing your own under the hood, check it out, I don't have the time to go into that, we'll cover that in the docs. We have two things left, we'll talk about scaffold and navigation. Let's start with scaffold. Scaffold, easy to make sure that the components are properly positioned and working together correctly with the material design structure. For instance, with mobile, it provides slots for the top level material component. Like top bar, bottom bar, action button, all of that stuff. In this case, we look at this mobile app, you can see that it has a bottom bar, if you have a drawer, you swipe left to drawer menu, the scaffold handle, it makes it easier for you, then obviously you have the content in there. The idea is that some of that stuff is kind of above your screen, as you change those out, that stuff stays the same, obviously you customize it a little bit. For the most part, it stays the same. We have the same idea with wear. We only have three main ones outside of the content. We have time text, it is straightforward, you have seen time text. That's going to give you the time at the top of the screen. It places it for you. It is nice. Next we have vignette, that's nice on the screen, hard to see here. You can imagine, that's on the screen. Finally, we have the position indicator, and this is also known as the scrolling indicator which let's you know where you are in the composable below and you're asking why do we put this in the scaffold, you put the curvature of the screen, the position has to be centered on the watch, not just the view port because otherwise it could be cut-off. For example, here, you can see this is a Fitness+, that part does not move. The scrollable portion below it, it does. That's moved up to the scaffold level. Finally, we have content. Before moving forward, I would just like to talk about the scaffold design first. That's important. It took me a little while to get my head wrapped around it. When it did, I always want to make sure that I engrain this in people's head. The first thing to do, you set the app, you do the materials themes like you're used to doing for the look and feel of the app. You put the scaffold and after that you put the content. If you are doing this in mobile, it is the same thing, same recommendation. It is just below the theme, above the content. All right. Let's look at code. In our example, our content inside of the scaffold is a scaling lazy column so that we hoist the state up here to support the position indicator. Let's look that the a little bit deeper. Because of the position, as I talked about a little bit earlier, it lives outside of the content, you have to hoist the state above the scaffold. Again, this is because we just don't want to cut it off. On all of the other screens, they don't take up all of the sides. There are other benefits as well. You check the scrolling state so that you make the time disappear with the controlling to get the screen real estate. If you wt to learn more about state, check out the composed State of mind, it is really great and he'll explain a bunch of stuff about state and how it all works together and he'll touch on the scaffold stuff. Okay. So we have hoisted the state up for the position indicator. By the way, the position indicator supports many different options. For scrolling, so in our case, we're using the scaling lazy list. You could use a scaling -- a scaling lazy list state and you could use that scrolling state, the lazy list state and we have other cool stuff rotating side buttons and there are a lot of options. Check out the docs. Enough of that. Let's get on. Easterly theme, scaffold, content inside. I won't spell that out. Let's look at the parameters. Modifier, the same. Time text, so you're used to the time text on -- that I showed earlier. Same thing, you drop it right in there, so you don't have to cover that. Vignette, it is easy, you set the position, in this case, we're doing top and bottom. Finally, we set the position indicator. Let's pull that out, see what that looks like. In this case, I'm looking at the scrolling, I don't show that unless it is scrolling. Here is the important part. The position indicator requires the state and this the main reason we hoisted that up from the lazy column. We pass that in. There we go. When you scroll the content, you get a nice little scrolling bar and you have the time on the top. These will all stay visible when moving between the screens to scroll obviously, the time will, if you have a a vignete as well. The earlier slide, you remember I mentioned you replace the wear navigation dependency, we'll call that again. Technically, you can use the mobile one, you will have bad time, right. The wear navigation, it is optimized obviously for wear. The same design as I talked about earlier with the scaffold, this is the same design as mobile. You have the app, the material theme, the scaffold, then normally mobile, you have the app host here, in our case, we're wearing the wear equivalent, we have the swipe dismissible, and you guess from the name, it supports swipe away. It is just like the box. Any of the content. It handles swiping, I just said that. Then the nice thing, you will see as you get to raise the knowledge, from mobile. This is the code. The material theme, scaffolding, we set those as before, the navigation code, it goes here. In this case, we create a controller. We have the specific one for the swipe dismissible version. Remember swipe dismissible nav controller, a mouth full, it is explains what it is pretty well. You use the swipe dismissal host and pass the controller, you have the destination with the route. You put the main screen content right here. In this case, it is the same code that you used on mobile, composable, you use it the same way to set the screens. You will have something like this, you swipe away, it goes to the screen before. You set all of the stuff up. All right. Let's recap. First, we're in developer preview now. We have had a lot of Alpha releases. We're ready for your feedback. Compose, make sure you set the right dependcy, you want to replace material and you want to add foundation and if you are using navigation replace that as well. All of that knowledge that you built up translates directly to compose, you build beautiful UIs fast. Like the mobile Alphas in the developer previews, we want to include the feedback. Make sure you give it to us, it leads us to the last slide. D.android.com sample,e lab, guides, most importantly, we have looked for feedback to incorporate that. Your time is valuable. Thank you for spending it with us. Happy coding!. Thank you! >> We hope that you are excited about the recent Android 12 launch. In this session we will highlight the biggest compatibility changes in Android 12 and share tips on how to give your users a smooth transition to the latest release. While there are a ton of new capabilities to explore, we'll start by testing the current app with a compatible update first. As people update the devices to Android 12 it is basic and critical level of quality that ensures users have a good experience. Among this talk, you will hear some inspirational stories and recommendations from apps on how they have made the most of Android 12 features and how they can do the same in the apps. First thing first. Let's learn about the key platform changes in this release. There are two main types of compatibility changes, those affect all apps running by default, those that only affect apps based on the declared level. To make it easier, we will leave the target at the level and in the Corper of the slide, for those changes, they only affect apps, they target the new west Android 12 and this introduced the biggest visual refresh covered by a new personal material design. We have focused on simplifying and polishing the existing experiences and helping you to build beautiful, secure, performing apps, tailored to user needs. To bring this change to life, we have centered our efforts on three main areas, user interface, performance, privacy. In this session, we will review the Android changes related to user interface and performance and to learn about privacy updates, make sure you hear our other talk about privacy by design. Let's continue with the UI changes to give a consistent and intuitive up user experience. We have made changes to improve the responsiveness, starting in Android 12, the system always applies the new default screen on called and on up starts. Such splash screen is constructed with the app launcher icon and the window background of the theme. The new experience works out of the box for all apps running on Android 12. However, if you implement a custom splash screen you need to migrate to the new splash screen API. We encourage using jet packs splash screen library to enable the compatibility and create a consistent look and feel across all Android versions. The splash screens are fully customizable, you can remove the splash screen activity altogether, even if it is used, and in this way, you avoid the duplication of splash screens and reduce the loading time. There are different techniques for doing that, you can learn more in our immigration guide and developer site. Android 12 changes appearance and behavior of fully custom notifications, the visually consistent and easy to scan with the discoverable familiar yal notification expansion for users. Previously custom notifications were able to use the entire notification area and provide their own layout and styles. For Android 12, notifications with custom content views will no longer use the full notification area. Instead, the system applies standard tem plates. This template ensures that custom notifications have the same decoration as other notifications in all states such as icon, expansion and collapse state accordances. The change effects the defined custom sub classes of notifications style or the notification, the methods to set the custom content view. If the app is using fully customized notifications, make sure that you test how they work with the new template. Android 12 also consolidates existing behavior to make it easier for users to perform virtual navigation while in an immersive mode. The existing behaviors, the experience, they're now duplicated, they are replaced with the new default behavior that allows users to form the navigation comments only with one swipe instead of two required on Android 11. If you're developing a full screen gaming experience, you can still protect users from accidental engagement in immersive mode with the dedicated file. >> Let's now dive through the changes that affect actual and perceived app performance for users. Foreground services are a great tool that allows Android system to ensure resources for completing one user initiated task at a high priority. However, they are often misused. We found that half of the services are launched from the background, which leads to many issues including those related to battery trained, user confusion when a user is in an expected foreground service notification. Hence starting from Android 12 we will disallow starting foreground services from background and restrict the launching foreground services to visible activities and user actions. There are less common use cases, handling the broadcast receivers or the manager app, for the full list ever exemptions for foreground launch restrictions, first the documentation on our developer site. Earlier this year we introduced expedited jobs as part of WorkManager jetpack library. This is our low latency jobs that can be invoked from either foreground or background to be executed right away. They can run in low power modes and we encourage developers to use them instead of launching foreground services when possible. In most cases, apps should use this with the advantage of being battery friendly, for special cases, alarm clocks, timers, you can use exact alarms. In Android 12 we're adding a new manifest permission to give visibility and control over the apps that have the permission. We have added a new API to let you check the permission status of the app. For user, app start-up is important so that they can keep focused on their task. Therefore, in the Android 12 we're introducing new features and some changes in behavior for app start-up aimed at making users productive and happy. We have already covered new splash screen animations and now we will cover a couple more changes, starting with the notification tamp leans, some use intermediate components, such as broadcast receivers and services, when handling the taps on notificationings. Those are known as notification tramp pellings and they often lead to delays and interactive user flow. If the app uses this, use this command to see what component was launched when the user interacted with the notification. Android supports a notion of app links that let's URLs directly linked to an install app bypassing the configuration dialogue entirely. The improved user experience, by removing friction from user journeys. Applings are different from deep links, and that links only handle the ski Ma while deep links, they're any ski Ma. Probably the most important app links behavior change, Android 12 had always open the default browser for non-verified links. If you have configuration error, they are limited, the verification manager, APIs, they let you check for domain verification states and if needed, they take the user to settings for them to approve domains for the apps and learn more on the developer site. >> Now we have learn bad the new features and changes in Android 12, we'll look at the testing and tooling to make the apps compatible. In Android 11 we have introduced the compatibility framework tools to make it easier to test and to back up against changes. With this, you can turn on and off breaking changes individually and evaluate how it is important in the app. In this way, you can isolate and test against only one behavior change at a time. You can easily enable changes behind the targets. You can check which behavior changes are currently enabled using the developer options located or the comments. For each behavior change, the first time when you have the pecked API, the system outputs a message like this. You can identify the compatibility changes known to the system and the current overrides using the following command. Each change in the list has a name, changing reference and whether it is enabled or disabled. Each command is used to toggle the changes on or off for certain packages, not only to change the target version or the compiling of the basic testing. Android platform will automatically adjust the internal logic. Changes are individuallying toable, you can isolate, test, look at the behavior change one by one or disable a single change that is causing issues. Changes can be only toggled for the debugable apps, if you don't see the app in compatibility framework, make sure that you set the app debugable in the manifest. Keep in mind, that on release and rebuild, the changes that affect all apps, they can be overwritten. We have the apps to validate the up linking for the application, you can use comments to varyvy the links manually on a device or add to the continuous integration tool chain. Look for the development for editing and testing. We have checks to check where the code may be affected by the Android 12 changes such as custom declarations of splash screens, course location permission for location usage, media formats, many more. To get started, set up the Android 12SDK. Now we want to showcase the developers which are adopted with changes so that the users will take advantage of the new experience. >> This allows users to sync devices via bluetooth. Android 12 has new permissions that decouples the scanning from location permission. The location permissions and their relation to bluetooth are difficult to explain to end users and the privacy level. For a few years, we had to invest in customer service topics and tutorials to allocate users about why the app needs location permissions to scan for bluetooth. Even with a good explanation, they had negative reviews for asking for location permission to scan for companion devices. Nearby devices permission is way more effective as it asks permission only for scanning and connecting. Coupled with tips from engineers, first, abstract logic for the permissions helping to control the entry points and testing efforts. Secondly, unit testings permission checks on all supported Android versions. Use the Android devices and test different upgrades scenarios to ensure that the app behaves correctly. To reduce the user friction, nearby device permission will be granted automatically when the user upgrades to Android 12 but only if the app already had a location permission granted in the previous Android version. To use the nearby device permission, you must declare bluetooth scan permission in the manifest file. This is a time permission, in addition to declaring it in the manifest, the app must check and request the permission, the run time, before initiating the device discovery. By declaring the user permission flags attribute, it is never full location, the developer indicates they don't plan on using the scan results to derive user location. If you only need to connect the devices, you can declare bluetooth connect permission. Let's look at one more Android developed change we have not previously covered. Very much over scroll affect. Most of the app also have this working out of the box on Android 12. There is a masking algorithm punching through the screen, when the contents are laid out or controlled, there isist will have the projections of message bubbles on the screen and you use that to create a mask to apply to a given gradient or solid colors. The engineering team was quick to come up with the solution using recycler view item decoration. Fixing the over scroll issue early let's signal app deliver the experience people expect from the devices without compromising the performance. Recommendations from signal team. Pay attention to blending modes and how they work with additional layers. Android 12 over scroll using an additional layer to render the stretching affect that will generate different results with various blending algorithms. Another important point is to ensure that the background is rendered by recycler view. Address the beta user feedback for compatibility ahead of the release. Signal out is a great example of delivering delightful user experience. Luckily, the signal private messager for Android is opensourced and you can check out their fix on github and you have the link below the description of the video. In this talk, we tried our best to cover the most important changes Android 12 brings to developers and ultimately to our users. For more changes, we encourage you to check them in devel developer.android.com. Most importantly, we would like to remind you, test your apps and confirm compatibility of the Android 12. Many developers already did, it is now time for you to get ready for this change and deliver great user experiences. We're looking forward to seeing your apps on the Android 12.