Tag Archives: Jetpack

Play Time with Jetpack Compose

Learn about Google Play Store’s strategy for adopting Jetpack Compose, how they overcame specific performance challenges, and improved developer productivity and happiness.

Posted by Andrew Flynn & Jon Boekenoogen, Tech leads on Google Play

In 2020, Google Play Store engineering leadership made the big decision to revamp its entire storefront tech stack. The existing code was 10+ years old and had incurred tremendous tech debt over countless Android platform releases and feature updates. We needed new frameworks that would scale to the hundreds of engineers working on the product while not negatively impacting developer productivity, user experience, or the performance of the store itself.

We laid out a multi-year roadmap to update everything in the store from the network layer all the way to the pixel rendering. As part of this we also wanted to adopt a modern, declarative UI framework that would satisfy our product goals around interactivity and user delight. After analyzing the landscape of options, we made the bold (at the time) decision to commit to Jetpack Compose, which was still in pre-Alpha.

Since that time, the Google Play Store and Jetpack Compose teams at Google have worked extremely closely together to release and polish a version of Jetpack Compose that meets our specific needs. In this article we'll cover our approach to migration as well as the challenges and benefits we found along the way, to share some insight into what adopting Compose can be like for an app with many contributors.

Play Store rewrote their UI with 50% less code with Compose

Considerations

When we were considering Jetpack Compose for our new UI rendering layer, our top two priorities were:

  1. Developer Productivity: Play Store team has hundreds of engineers contributing to this code, so it should be easy (and fun) to develop against.
  2. Performance: Play Store renders lots of media-heavy content with many business metrics that are very sensitive to latency and jank, so we needed to make sure it performed well across all devices, especially low-memory hardware and Android (Go Edition) devices.

Developer Productivity

We have been writing UI code using Jetpack Compose for over a year now and enjoy how Jetpack Compose makes UI development more simple.

We love that writing UI requires much less code, sometimes up to 50%. This is made possible by Compose being a declarative UI framework and harnessing Kotlin’s conciseness. Custom drawing and layouts are now simple function calls instead of View subclasses with N method overrides.

Using the Ratings Table as an example:

ratings table

With Views, this table consists of:

  • 3 View classes total, with 2 requiring custom drawing for the rounded rects, and stars
  • ~350 lines of Java, 55 lines of XML

With Compose, this table consists of:

  • All @Composable functions contained in the same file and language!
  • ~210 lines of Kotlin

buffering GIF

Animations are a hailed feature of Compose for their simplicity and expressiveness. Our team is building motion features that delight our Play Store users more than ever with Compose. With Compose’s declarative nature and animations APIs, writing sequential or parallel animations has never been easier. Our team no longer fears all the corner cases of animations around cancellation and call back chaining. Lottie, a popular animation library, already provides Compose APIs that are simple to work with.

Now you might be thinking: this all sounds great, but what about library dependencies that provide Views? It's true, not all library owners have implemented Compose-based APIs, especially when we first migrated. However, Compose provides easy View interoperability with its ComposeView and AndroidView APIs. We successfully integrated with popular libraries like ExoPlayer and YouTube’s Player in this fashion.

Headshot of Andrew

Performance

The Play Store and Jetpack Compose teams worked closely together to make sure Compose could run as fast and be as jank-free as the View framework. Due to how Compose is bundled within the app (rather than being included as part of the Android framework), this was a tall order. Rendering individual UI components on the screen was fast, but end to end times of loading the entire Compose framework into memory for apps was expensive.

One of the largest Compose adoption performance improvements for the Play Store came from the development of Baseline Profiles. While cloud profiles help improve app startup time and have been available for some time now, they are only available for API 28+ and are not as effective for apps with frequent (weekly) release cadences. To combat this, the Play Store and Android teams worked together on Baseline Profiles: a developer-defined, bundled profile that app owners can specify. They ship with your app, are fully compatible with cloud profiles and can be defined both at the app-level of specificity and library-level (Compose adopters will get this for free!). By rolling out baseline profiles, Play Store saw a decrease in initial page rendering time on its search results page of 40%. That’s huge!

Re-using UI components is a core mechanic of what makes Compose performant for rendering, particularly in scrolling situations. Compose does its best to skip recomposition for composables that it knows can be skipped (e.g. they are immutable), but developers can also force composables to be treated as skippable if all parameters meet the @Stable annotation requirements. The Compose compiler also provides a handy guide on what is preventing specific functions from being skippable. While creating heavily re-used UI components in Play Store that were used frequently in scrolling situations, we found that unnecessary recompositions were adding up to missed frame times and thus jank. We built a Modifier to easily spot these recompositions in our debug settings as well. By applying these techniques to our UI components, we were able to reduce jank by 10-15%.

Recomposition visualization Modifier in action

Recomposition visualization Modifier in action. Blue (no recompositions), Green (1 recomposition).

Another key component to optimizing Compose for the Play Store app was having a detailed, end-to-end migration strategy for the entire app. During initial integration experiments, we ran into the Two Stack Problem: running both Compose and View rendering within a single user session was very memory intensive, especially on lower-end devices. This cropped up both during rollouts of the code on the same page, but also when two different pages (for example, the Play Store home page and the search results page) were each on a different stack. In order to ameliorate this startup latency, it was important for us to have a concrete plan for the order and timeline of pages migrating to Compose. Additionally, we found it helpful to add short-term pre-warming of common classes as stop-gaps until the app is fully migrated over.

Compose unbundling from the Android framework has reduced the overhead in our team directly contributing to Jetpack Compose, resulting in fast turnaround times for improvements that benefit all developers. We were able to collaborate with the Jetpack Compose team and launch features like LazyList item type caching as well as move quickly on lightweight fixes like extra object allocations.

Headshot of Jon

Looking Ahead

The Play Store’s adoption of Compose has been a boon for our team’s developer happiness, and a big step-up for code quality and health. All new Play Store features are built on top of this framework, and Compose has been instrumental in unlocking better velocity and smoother landings for the app. Due to the nature of our Compose migration strategy, we haven’t been able to measure things like APK size changes or build speed as closely, but all signs that we can see look very positive!

Compose is the future of Android UI development, and from the Play Store’s point of view, we couldn’t be happier about that!

Jetpack Compose 1.1 is now stable!

Posted by Florina Muntenescu, Android Developer Relations Engineer

Blue background with phone icon

Today, we’re releasing version 1.1 of Jetpack Compose, Android's modern, native UI toolkit, continuing to build out our roadmap. This release contains new features like improved focus handling, touch target sizing, ImageVector caching, and support for Android 12 stretch overscroll. Compose 1.1 also graduates a number of previously experimental APIs to stable and supports newer versions of Kotlin. We've already updated our samples, codelabs, and Accompanist library to work with Compose 1.1.

New stable features and APIs

Image vector caching

Compose 1.1 introduces image vector caching bringing big performance improvements. We’ve added a caching mechanism to painterResource API to cache all instances of ImageVectors that are parsed with a given resource id and theme. The cache will be invalidated on configuration changes.

Touch target sizing

With respect to Compose 1.0, Material components will expand their layout space to meet Material accessibility guidelines touch target size. For instance, a RadioButton's touch target will expand to a minimum size of 48x48dp, even if you set the RadioButton's size to be smaller. This aligns Compose Material to the same behavior of Material Design Components, providing consistent behavior if you mix Views and Compose. This change also ensures that when you create your UI using Compose Material components, minimum requirements for touch target accessibility will be met.

If you find this change breaks existing layout logic, set LocalMinimumTouchTargetEnforcement to false to disable this behavior, but please be mindful this might reduce the usability of your app, and should be used with caution.

RadioButton touch target update 
Left: Compose 1.0, right: Compose 1.1 
 

RadioButton touch target update
Left: Compose 1.0, right: Compose 1.1

Experimental to stable APIs

Several APIs graduated from experimental to stable. Highlights include:

New experimental APIs

We’re continuing to bring new features to Compose. Here are a few highlights:

  • AnimatedContent can now be saved and restored when using rememberSaveable.
  • LazyColumn/LazyRow item positions can be animated using Modifier.animateItemPlacement().
  • You can use the new BringIntoView API to send a request to parents so that they scroll to bring an item into view.

Try out the new APIs using @OptIn and give us feedback!

Note: Using Compose 1.1 requires using Kotlin 1.6.10. Check out the Compose to Kotlin Compatibility Map for more information.

Wondering what’s next? Check out our updated roadmap to see the features we’re currently thinking about and working on, such as lazy item animations, downloadable fonts, moveable content, and more!

Jetpack Compose is stable, ready for production, and continues to add the features you’ve been asking us for. We’ve been thrilled to see tens of thousands of apps start using Jetpack Compose in production already and we can’t wait to see what you’ll build!

We’re grateful for all of the bug reports and feature requests submitted to our issue tracker over the Alphas and Betas - they help us to improve Compose and build the APIs you need. Do continue providing your feedback and help us make Compose better!

Happy composing!

Announcing Glance: Tiles for Wear OS made simple

Posted by Anna Bernbaum, Associate Product Manager


Last year we announced the Wear Tiles API. To complement that Java API, we are excited to announce that support for Wear OS Tiles has been added to Glance, a new framework built on top of Jetpack Compose designed to make it easier to build for surfaces outside your app on Android. We'd love to get your feedback on this alpha version.

Tiles provide Wear OS users easy access to the information and actions they need in order to get things done quickly. They also are one of the most used surfaces on Wear OS. Just one swipe away from the Watch Face, users can quickly access the most important information or actions from an app, like start a timer or get the latest weather forecast.


Watch face gif


Let's see how we can create a Tile with Glance:


class HelloTileService : GlanceTileService() {
   @Composable
   override fun Content() {
       Text(text = "Hello Glance")
   }
}

The simple code above generates the Tile below.


“Hello Glance” Tile sample with Glance

“Hello Glance” Tile sample with Glance


Note: Using Glance-wear-tiles requires`minSdkVersion`>= 26.



How it works

Glance creates “glanceable” experiences across Android surfaces using a base-set of Composables. For Tiles on Wear OS, Glance translates Composables into Tiles.


Diagram: Glance structure 

Diagram: Glance structure


Glance requires Compose to be enabled and depends on Runtime, Graphics, and Unit UI Compose layers, but it’s not directly interoperable with other existing Jetpack Compose UI elements, like Compose for Wear OS.

What’s in the Alpha

This initial release introduces the main APIs to build wear Tiles:

We are working on bringing even more functionality with default theming, further Android Studio support, and more. Stay tuned for new releases.

Get started with Glance

For a quick start, take a look at the samples in the AndroidX repository. Glance works with the latest stable Android Studio, although since Glance relies on Compose Runtime, follow the steps on the Jetpack Compose docs to set it up first.

The Alpha version is your opportunity to influence the APIs, so please share your feedback and let us know your experience!

Happy Composing with Glance!

Announcing Jetpack Glance Alpha for app widgets

Posted by Marcel Pintó Biescas, Developer Relations Engineer, @marxallski

Illustration of a laptop with the Android rocket logo

Android 12 revamps a key feature for many Android users, App Widgets, making them more useful, beautiful, and discoverable (84% use at least 1 widget). Today, we’re making it even easier to build them by releasing the first alpha of Jetpack Glance, a new framework built on top of the Jetpack Compose runtime designed to make it faster and easier to build app widgets for the home screen and other surfaces.

We’d love you to give it a try and share your feedback!

Glance offers similar modern, declarative Kotlin APIs that you are used to with Jetpack Compose, helping you build beautiful, responsive app widgets with way less code.

Glance “Hello World” widget sample

Glance “Hello World” widget sample


class GreetingsWidget(private val name: String): GlanceAppWidget() {
    @Composable
    override fun Content() {
        Text(text = "Hello $name")
    }
}

class GreetingsWidgetReceiver : GlanceAppWidgetReceiver() {

    override val glanceAppWidget = GreetingsWidget("Glance")
}

How it works

Glance provides a base-set of Composables to help build “glanceable” experiences. Starting today with app widget components but with more coming. Using the Jetpack Compose runtime, Glance can translate Composables into actual RemoteViews, and display them in an app widget.


Diagram: Glance structure

Diagram: Glance structure


This means that Glance requires Compose to be enabled and depends on Runtime, Graphics, and Unit UI Compose layers, but it’s not directly interoperable with other existing Jetpack Compose UI elements. However, state or any other logic within your app can be shared to create a glanceable UI.


What's in Alpha

This initial release introduces the main APIs to enable you to build app widgets in addition to providing interoperability with existing RemoteViews.

Here’s an overview of what the library offers, at a glance:

We are working on bringing even more functionality with default theming, further Android Studio support, and more. Stay tuned for new releases.



Get started with Glance

Check out the sample on GitHub for a quick start. Glance works with the latest stable Android Studio, although since Glance relies on Compose Runtime, follow the steps on the Jetpack Compose docs to set it up first.

In addition, for a more advanced showcase, checkout the demos in the AndroidX repository.


ResponsiveAppWidget.kt demo

ResponsiveAppWidget.kt demo

The Alpha version is your opportunity to influence the APIs, so please share your feedback and let us know your experience!

Happy Composing with Glance!

Beta 1 Update for 12L feature drop!

Posted by Maru Ahues Bouza, Director, Android Developer Relations

Image showing different kinda of large screens

At Android Dev Summit in October we highlighted the growth we’re seeing in large screen devices like tablets, foldables, and Chromebooks. We talked about how we’re making it easier to build great app experiences for these devices through new Jetpack APIs, tools, and guidance. We also introduced a developer preview of 12L, a feature drop for Android 12 that’s purpose-built for large screens.

With 12L, we’ve optimized and polished the system UI for large screens, made multitasking more powerful and intuitive, and improved compatibility support so apps look better right out of the box. 12L also includes a handful of new APIs for developers, such as for spatial audio and improved drag-and-drop for accessibility.

Today we’re releasing the first Beta of 12L for your testing and feedback as you get your apps ready for the feature drop coming early next year. You can try the new large screens features by setting up an Android emulator in Android Studio. 12L is for phones, too, and you can now enroll here to get 12L Beta 1 on supported Pixel devices. If you are still enrolled in the Android 12 Beta program, you’ll get the 12L update automatically. Through a partnership with Lenovo, you can also try 12L on the Lenovo Tab P12 Pro tablet, see the Lenovo site for details on available builds and support.

What’s in 12L Beta 1?

Today’s Beta 1 build includes improvements to functionality and user experience as well as the latest bug fixes, optimizations, and the December 2021 security patches. For developers, we’ve finalized the APIs early, so Beta 1 also includes the official 12L APIs (API level 32), updated build tools, and system images for testing. These give you everything you need to test your apps with the 12L features.

With 12L, we’ve focused on refining the UI on large screen devices, across notifications, quick settings, lockscreen, overview, home screen, and more. For example, on screens above 600dp, the notification shade, lockscreen, and other system surfaces use a new two-column layout to take advantage of the screen area.


Image showing a two-column layout

Two-column layouts show more and are easier to use


Multitasking is also more powerful and intuitive - 12L includes a new taskbar on large screens that lets users instantly switch to favorite apps on the fly or drag-and-drop apps into split-screen mode. Remember, on Android 12 and later, users can launch any app into split screen mode, regardless whether the app is resizable. Make sure to test your apps in split screen mode!


GIF showing the drag and drop in split screen mode

Drag and drop apps into split-screen mode


Last, we’ve improved compatibility mode with visual and stability improvements to offer a better letterboxing experience for users and help apps look better by default. If your app is not yet optimized for large screens, make sure to test your app with the new letterboxing.

More APIs and tools to help you build for large screens

As you optimize your apps for large screens, here are some of our latest APIs and tools that can make it easier to build a great experience for users.

  • Material patterns for large screens - Our new Material Design guidance can help you plan how to scale your app’s UI across all screens.
  • Jetpack Compose for adaptive UI - Jetpack Compose makes it very easy to handle UI changes across different screen sizes or components. Check out the Build adaptive layouts in Compose guide for the basics of what you need to know.
  • Window Size Classes for managing your UI - Window Size Classes are opinionated viewport breakpoints to help you more easily design, develop and test resizable application layouts. Watch for these coming soon in Jetpack WindowManager 1.1.
  • Activity embedding - With Activity embedding APIs you can take advantage of the extra display area on large screens by showing multiple activities at once, such as for the List-Detail pattern, and it requires little or no refactoring of your app. Available in Jetpack WindowManager 1.0 Beta 03 and later.
  • Visual linting in Android Studio - In Android Studio Chipmunk, try the new visual linting tool that proactively surfaces UI warnings and suggestions in Layout Validation, to help identify potential issues on large screens.
  • Resizable emulator - This new emulator configuration comes with Android Studio Chipmunk and lets you quickly toggle between the four reference devices - phone, foldable, tablet, and desktop for easier testing.

Make sure to check out all of our large screens developer resources for details on these and other APIs and tools.

Get started with 12L on a device!

With the 12L feature drop coming to devices early next year, now is a great time to optimize your apps for large screens. For developers, we highly recommend checking out how your apps work in split screen mode with windows of various sizes. If you haven’t optimized your app yet, see how it looks in different orientations and try the new compatibility mode changes if they apply.

The easiest way to get started with the large screen features is using the Android Emulator in a foldable or tablet configuration - see the complete setup instructions here.

Now you can also flash 12L onto a large screen device. Through a partnership with Lenovo, you can try 12L preview builds on the Lenovo Tab P12 Pro. Currently Lenovo is offering a Developer Preview 1 build, with updates coming in the weeks ahead. Visit Lenovo's 12L preview site for complete information on available builds and support.

12L is coming to phones, too, and although you won’t see the large screen features on smaller screens, we welcome you to try out the latest improvements in this feature drop. Just enroll your supported Pixel device here to get the latest 12L Beta update over-the-air. If you are still enrolled in the Android 12 Beta program, you’ll automatically receive the update 12L.

For details on 12L and the release timeline, visit the 12L developer site. You can report issues and requests here, and as always, we appreciate your feedback!

12L and new Android APIs and tools for large screens

Posted by Dave Burke, VP of Engineering

image shows four devices illustrating 12L and new Android APIs and tools for large screens

There are over a quarter billion large screen devices running Android across tablets, foldables, and ChromeOS devices. In just the last 12 months we’ve seen nearly 100 million new Android tablet activations–a 20% year-over-year growth, while ChromeOS, now the fastest growing desktop platform, grew by 92%. We’ve also seen Foldable devices on the rise, with year on year growth of over 265%! All told, there are over 250 million active large screen devices running Android. With all of the momentum, we’re continuing to invest in making Android an even better OS on these devices, for users and developers.

So today at Android Dev Summit, we announced a feature drop for Android 12 that is purpose-built for large screens, we’re calling it 12L, along with new APIs, tools, and guidance to make it easier to build for large screens. We also talked about changes we’re making to Google Play to help users discover your large-screen optimized apps more easily. Read on to see what’s new for large screens on Android!

Previewing 12L: A feature drop for large screens

Today we're bringing you a developer preview of 12L, our upcoming feature drop that makes Android 12 even better on large screens. With the preview, you can try the new large screen features, optimize your apps, and let us know your feedback.

In 12L we’ve refined the UI on large screens across notifications, quick settings, lockscreen, overview, home screen, and more. For example, on screens above 600dp, the notification shade, lockscreen, and other system surfaces use a new two-column layout to take advantage of the screen area. System apps are also optimized.

image shows a phone with two-column layouts

Two-column layouts show more and are easier to use

We’ve also made multitasking more powerful and intuitive - 12L includes a new taskbar on large screens that lets users instantly switch to favorite apps on the fly. The taskbar also makes split-screen mode more discoverable than ever - just drag-and-drop from the taskbar to run an app in split-screen mode. To make split-screen mode a better experience in Android 12 and later, we’re helping users by automatically enabling all apps to enter split screen mode, regardless whether the apps are resizable.

GIF image shows maps and web brower on the screen at the same time

Drag and drop apps into split-screen mode

Last, we’ve improved compatibility mode with visual and stability improvements to offer a better letterboxing experience for users and help apps look better by default. We’ve made letterboxing easily customizable by device manufacturers, who can now set custom letterbox colors or treatments, adjust the position of the inset window, apply custom rounded corners, and more.

We plan to release the 12L feature drop early next year, in time for the next wave of Android 12 tablets and foldables. We’re already working with our OEM partners to bring these features to their large screen devices - watch for the developer preview of 12L coming soon to the Lenovo P12 Pro. With the features coming to devices in the few months ahead, now is a great time to optimize your apps for large screens.

For developers, we highly recommend checking out how your apps work in split screen mode with windows of various sizes. If you haven’t optimized your app yet, see how it looks in different orientations and try the new compatibility mode changes if they apply. Along with the large screen features, 12L also includes a handful of new APIs for developers, along with a new API level. We’ve been careful not to introduce any breaking changes for your apps, so we won’t require apps to target 12L to meet Google Play requirements.

To get started with 12L, download the 12L Android Emulator system images and tools from the latest preview release of Android Studio. Review the features and changes to learn about areas to test in your apps, and see preview overview for the timeline and release details. You can report issues and requests here, and as always, we appreciate your feedback!

12L is for phones, too, but since most of the new features won’t be visible on smaller screens, for now we’re keeping the focus on tablets, foldables, and ChromeOS devices. Later in the preview we plan to open up Android Beta enrollments for Pixel devices. For details, visit developer.android.com/12L.

Making it easier to build for large screens

It's time to start designing fully adaptive apps to fit any screen, and now we're making it even easier. To help you get ready for these changes in the OS and Play, along with the developer preview we're releasing updates to our APIs, tools and guidance.

Design with large screen patterns in mind

The first step to supporting adaptive UI is designing your app to behave nicely on both a small and a larger screen. We’ve been working on new Material Design guidance that will help you scale your app’s UI across all screens. The guidance covers common layout patterns prevalent in the ecosystem that will help inspire and kick-start your efforts.

Image shows four Adaptive UI patterns in the Material Design guidelines

Adaptive UI patterns in the Material Design guidelines

Build responsive UIs with new navigation components

To provide the best possible navigation experience to your users, you should provide a navigation UI that is tailored to the Window Size Class of the user’s device. The recommended navigation patterns include using a navigation bar for compact screens and a navigation rail for medium-width device classes and larger (600dp+). For expanded-width devices, there are several ideas on larger screen layouts within our newly released Material Design guidance such as a List/Detail structure that can be implemented, using SlidingPaneLayout. Check out our guidance on how to implement navigation for adaptive UIs in Views and Compose.

While updating the navigation pattern and using a SlidingPaneLayout is a great way to apply a large screen optimized layout to an existing application with fragments, we know many of you have applications based on multiple activities. For those apps, the new activity embedding APIs released in Jetpack WindowManager 1.0 beta 03 make it easy to support new UI paradigms, such as a TwoPane view. We’re working on updating SlidingPaneLayout to support those APIs - look for an update in the coming months.

Use Compose to make it easier to respond to screen changes

Jetpack Compose makes it easier to build for large screens and diverse layouts. If you’re starting to adopt Compose, it’s a great time to optimize for large screens along the way.

Compose is a declarative UI toolkit; all UI is described in code, and it is easy to make decisions at runtime of how it should adapt to the available size. This makes Compose especially great for developing adaptive UI, as it is very easy to handle UI changes across different screen sizes or components. The Build adaptive layouts in Compose guide covers the basics of what you need to know.

Use WindowManager APIs to build responsive UIs

The Jetpack WindowManger library provides a backward-compatible way to work with windows in your app and build responsive UI for all devices. Here’s what’s new.

Activity embedding

Activity embedding lets you take advantage of the extra display area of large screens by showing multiple activities at once, such as for the List-Detail pattern, and it requires little or no refactoring of your app. You determine how your app displays its activities—side by side or stacked—by creating an XML configuration file or making Jetpack WindowManager API calls. The system handles the rest, determining the presentation based on the configuration you’ve created.

Activity embedding works seamlessly on foldable devices, stacking and unstacking activities as the device folds and unfolds. If your app uses multiple activities, activity embedding can enhance your user experience on large screen devices. Try the activity embedding APIs in Jetpack WindowManager 1.0 Beta 03 and later releases. More here.

GIF shows activity embedding with Jetpack WindowManager

Activity embedding with Jetpack WindowManager

Use Window size classes to help detect the size of your window

Window Size Classes are a set of opinionated viewport breakpoints for you to design, develop and test resizable application layouts against. The Window Size Class breakpoints have been split into three categories: compact, medium, and expanded. They have been designed specifically to balance layout simplicity with the flexibility to optimize your app for the most unique use cases, while representing a large proportion of devices in the ecosystem. The WindowSizeClass APIs will be coming soon in Jetpack WindowManager 1.1 and will make it easier to build responsive UIs. More here.

Image compares the width of Window Size Classes by showing compact, medium, and expanded views

Window Size Classes in Jetpack WindowManager

Make your app fold-aware

WindowManager also provides a common API surface for different window features, like folds and hinges. When your app is fold aware, the content in the window can be adapted to avoid folds and hinges, or to take advantage of them and use them as natural separators. Learn how you can make your app fold aware in this guide.

Building and testing for large screens with Android Studio

Reference Devices

Since Android apps should be built to respond and adapt to all devices and categories, we’re introducing Reference Devices across Android Studio in many tools where you design, develop and test UI and layout. The four reference devices represent phones, large foldable inner displays, tablets, and desktops. We’ve designed these after analyzing market data to represent either popular devices or rapidly growing segments. They also enable you to ensure your app works across popular breakpoint combinations with the new WindowSizeClass breakpoints, to ensure your app covers as many use cases as possible.

Image shows reference device definitions for a tablet, phone, foldable, and desktop sizes

Reference Device definitions

Layout validation

If you’re not sure where to get started adapting your UI for large screens, the first thing you can do is use new tools to identify potential issues impacting large screen devices. In Android Studio Chipmunk, we’re working on a new visual linting tool to proactively surface UI warnings and suggestions in Layout Validation, including which reference devices are impacted.

Image shows layout validation panel. The panel shows phone, foldable, tablet, and desktop sizes

Layout validation tool with Reference Device classes

Resizable emulator

To test your app at runtime, we can use the new resizable emulator configuration that comes with Android Studio Chipmunk. The resizable emulator lets you quickly toggle between the four reference devices - phone, foldable, tablet, and desktop. This makes it easier to validate your layout at design time and test the behavior at runtime, both using the same reference devices. To create a new Resizable emulator, use the Device Manager in Android Studio to create a new Virtual Device and select the Resizable device definition with the Android 12L (Sv2) system image.

GIF shows the processs to create a new Resizable emulator

Resizable Android Emulator

Changes to Google Play on large screens

To make it easier for people to find the best app experiences on their tablets, foldables, and ChromeOS devices, we're making changes in Play to highlight apps that are optimized for their devices.

We’re adding new checks to assess each app’s quality against our large screen app quality guidelines to ensure that we surface the best possible apps on those devices. For apps that are not optimized for large screens, we’ll start warning large screen users with a notice on the app’s Play Store listing page.

We'll also be introducing large screen specific app ratings, as announced earlier this year, so users will be able to rate how your app works on their large screen devices. These changes are coming next year, so we're giving you advanced notice to get your apps ready!

Also, make sure to check out our post that highlights how we are evolving our business model to address developer needs in Google Play.


Learn more!

To help you get started with building for large screens and foldables, no matter whether you’re using Views or Compose, we’ve got you covered! We’re launching new and updated guidance on how to support different screen sizes both in a new and in an existing app, how to implement navigation for both Views and Compose, how to take advantage of foldable devices and more. Check them out in the large screens guides section for Views support or in the Compose guides section.

Nothing speaks louder than code - we updated the following samples to support responsive UIs:

For some hands-on work, check out our Support foldable and dual-screen devices with Jetpack WindowManager updated codelab.

Performance and Velocity: How Duolingo Adopted MVVM on Android

Posted by Kateryna Semenova, Android Developer Relations Engineer

illustration of hand holding up a chart with the Duolingo bird sitting on top

Executive Summary

Duolingo’s app began to experience growing pains due to scalability issues in their Android software architecture. They were able to solve these performance problems and regain developer productivity, by refactoring to a Model-View-ViewModel architecture and using Android Jetpack’s Dagger and Hilt for dependency injection. To learn more about how this impacted their business, read the accompanying article here.

Introduction

Duolingo is the world’s most popular language learning app, with over ten million daily learners, because they’ve managed to make something people found daunting feel easy and fun. This continued success relies on a constant stream of innovations and updates — and a smooth-running app that can deliver all of them. To Duolingo, a single unresponsive app in a device anywhere in the world could mean a learner potentially discouraged. This commits them to app excellence, particularly on the Android devices used by sixty percent of their learners, including their CEO, who keeps track of the app from an entry-level phone. And so, when Duolingo's Android development team registered an increase in “App not Responding” errors, dropped frames — and even received a hand-written complaint — they took action immediately.

Their situation wasn’t that uncommon. Apps that lack scalable architecture and clear best practices often perform well at the beginning but show signs of technical debt as they grow. Duolingo’s Android codebase was designed to allow them to add and release new features rapidly, but the lack of an agreed-upon architecture was manifesting in increasingly frequent performance regressions. It was starting to suffer from unreliable frame rates, visually inconsistent or broken interactions, and a growing assortment of new bugs. These regressions not only inconvenienced learners but also cost the team substantial development effort to diagnose and repair. Duolingo’s Android development team realized that if they wanted to keep shipping new features while providing the target level of user experience, a new approach to their codebase was needed.

Discovery

First, they had to get to the bottom of what exactly was going on. A deep dive into the numbers uncovered that, as they added new functionality, the app’s rendering performance was regressing 5-10% every month. In fact, one particularly unwieldy release had increased crashes by 10%, slowed frame renders by 25%, and saw lessons starting 70% slower on entry-level devices.

Further analysis of their code led them to the conclusion that most of the app’s issues could be traced back to a single bottleneck: a global state object called DuoState, which was responsible for maintaining state across different features of the app. A number of popular features (like experience points and daily streak tracking) were using it to access vital information. Centralizing their data in this way had once enabled the team to iterate rapidly. They simply added properties to DuoState whenever a new feature needed to share information across the app. But now the unoptimized and frequent access to the object was causing increasing performance regressions.

DuoState was so tightly coupled to the entire codebase that even small changes could impact the rest of the app. The team feared that a minor new feature could have the unforeseen side effect of triggering many internal updates to the app, causing the entire release to be too slow for many devices. These performance regressions became more frequent as the app grew, and the team onboarded new engineers to keep up with the accelerating product roadmap. In 2020, as they added more developers, they were starting to see significant regressions cropping up as often as every 90 days. Upon closer inspection, the likelihood of a regression in a given release was proportional to the number of changes it implemented. At this rate, these regressions would completely derail the product roadmap within a few years.

This outdated architecture had become a bottleneck for both the performance of the app and the velocity of the team. After much internal debate, they stopped development of new features, including some closely tied to their bottom line. For two full months, Duolingo’s development team went all-in on refactoring their Android app in an effort they called the “Android Reboot”.

The Android Reboot

One of the team’s first key takeaways was that their code lacked clear boundaries. The DuoState object was readily available at any point in the code, inviting developers to access it frequently in inefficient ways. They needed to create a greater separation of concerns within the codebase. They decided to tease apart each feature into its own, clearly-defined module, using the Model-View-ViewModel architectural pattern. MVVM allowed them to remove calls to the monolithic DuoState object, letting many modules work in separate threads.

Diagram showing before and after implementing the Model-View-ViewModel architectural pattern

The team’s familiarity with MVVM, and Google’s support for it, made it an obvious choice. It allowed them to clearly document what logic should go into what files (including views, view models and repositories). This helped make their feature architecture more consistent. With a clear path to follow, the team quickly began refactoring their monolithic code into sets of classes with clear boundaries and responsibilities.

Along with MVVM, the team used Dagger and Hilt (also included in Android Jetpack) to implement repository patterns to replace DuoState. Dagger generates clear readable code that provides verbose error logging designed to help developers understand exactly what their code is doing, eliminating dead stack traces to reflected properties; and Hilt reduces the amount of boilerplate code needed to write for this.

This new architecture allowed the team to split DuoState into smaller objects. This immediately reduced unnecessary coupling between domains. For example, the code responsible for tracking a user’s progress could now access their experience points but not the number of times they’ve logged in during a month. These new architecture guidelines meant that while no single thing was too difficult to change, it took coordination and planning to change it across the app. Implementing the new architecture across the code base drove significant performance gains in aggregate.

MVVM architecture facilitates a separation of concerns between the domain data, the interface the learners see, and the logic for how these two realms interact. It gave Duolingo’s developers a more deliberate way to control how the app responds to internal state updates. They could now develop more complex user experiences without the risk of triggering regressions, or affecting the underlying business rules.

Developer Productivity

In the past, inconsistent application of development patterns made different parts of the codebase harder to understand and maintain. Without consensus, each developer implemented code as they saw fit.

MVVM, Dagger, and Hilt, provided the team with a more detailed understanding of how new features should be implemented. Following these best practices made the code easier and more predictable. Developers could now assist in debugging features that they hadn’t originally worked on. And new developers could be onboarded more efficiently; as long as they understood the architecture, they could contribute meaningfully right away. This new clarity significantly boosted the team’s development velocity.

Ensuring Quality

Crucially, the new architecture also revealed that certain animation features in the app were underperforming on entry-level devices. Accordingly, the other core focus of the Android Reboot was the reduction of jank, dropped frames, and "App Not Responding” (ANR) errors. The team used repository patterns to help streamline the sharing of data between threads. These patterns ensured that they could more efficiently use device resources with multiple threaded modules. Moving work off the main thread improved responsiveness, overall frame rate, and led to smoother animations on entry-level devices. Performance on flagship devices improved as well.

A Better Overall Android Experience

In the six months working with the new architecture, Duolingo’s Android team has continued to ship new features without recording significant performance regressions. The days where they had to halt feature production to hunt and fix bugs are safely behind them.

The app’s daily ANR rate dropped 41%. The percentage of time that the app’s frame rate fell below target decreased by 28%. And importantly, users experienced a 40% increase in speed when scrolling through lessons, the leaderboard, and stories in the app.

The reboot allowed Duolingo to consistently provide their trademark fun, effective, and delightful language learning experience on a much wider range of Android devices.

Conclusion

Duolingo’s dedication to their mission made them the world's top app in the language learning space. Their commitment to app excellence — creating cutting edge educational experiences without compromising accessibility — is what kept them there.

If you’re interested in getting your team on board for your own Android Reboot, check out our condensed case study for product owners and executives linked here.

Jetpack Compose is now 1.0: announcing Android’s modern toolkit for building native UI

Posted by Anna-Chiara Bellini, Product Manager, Nick Butcher, Developer Relations

Today, we're launching version 1.0 of Jetpack Compose, Android's modern, native UI toolkit to help you build better apps faster. It's stable, and ready for you to adopt in production. We have been developing Compose in the open with feedback and participation from the Android community for the last two years. As we reach 1.0, there are already over 2000 apps in the Play Store using Compose - in fact, the Play Store app itself uses Compose! But that’s not all, we have been working with a number of top app developers and their feedback and support has helped us make the 1.0 release even stronger. Square, for instance, told us that by using Compose, they can “focus on things that are unique to Square and their UI infrastructure, rather than solving the broader issue of building a declarative UI framework”. Monzo said Compose allows them to “build higher quality screens more quickly”. And Twitter summed it up nicely: “We love it! ❤️

We designed Compose to make it faster and easier to build native Android apps. With a fully declarative approach, you just describe your UI, and Compose takes care of the rest. As app state changes, your UI automatically updates, making it a lot simpler to build UI quickly. Intuitive Kotlin APIs help you build beautiful apps with way less code, and native access to all existing Android code means you can adopt at your own pace. Powerful layout APIs and code-driven UI make it easy to support different form factors, like tablets and foldables, and Compose support is coming for WearOS, Homescreen Widgets, and more!

This 1.0 release is ready for use in production, offering key features that you need:

  • Interoperable: Compose is built to interoperate with your existing app. You can embed compose UIs within Views or Views within Compose. You can add as little as a single button to a screen, or keep that custom view you’ve created in a now Compose screen.
  • Jetpack Integration: Compose is built to integrate with the Jetpack libraries you already know and love. With integration with Navigation, Paging, LiveData (or Flow/RxJava), ViewModel and Hilt, Compose works with your existing architecture.
  • Material: Compose offers an implementation of Material Design components and theming, making it easy to build beautiful apps that reflect your brand. The Material theming system is easier to understand and trace, without having to consult multiple XML files.
  • Lists: Compose’s Lazy components offer a simple, succinct but powerful way to efficiently display lists of data, with minimal boilerplate.
  • Animation: Compose’s simple and coherent animation APIs make it far easier to delight your app’s users.


New Tools

The fully declarative approach in Jetpack Compose radically changes how you develop UI. To support new workflows and a different way of thinking, we are delivering new tools, designed specifically for Compose, and adding support for Compose to some of our existing tooling.

Compose Preview

The new Compose Preview, available in Android Studio Arctic Fox allows you to see your Composables in different states, light and dark theme, or different font scalings, all at the same time, making component development easier, without having to deploy a whole app to your device. Enhanced with live editing of literals, you can see updates without recompiling your project.


Deploy Preview

If you ever wished to be able to test parts of the UI on a device, without having to navigate through your app to the screen you’re working on, you will like the new Deploy Preview: just create a preview for your Composable, and deploy it on your device for fast iteration.

Compose support in Layout Inspector

Layout Inspector adds support for Composables, so that you can confidently mix Compose with existing Views.

Read more about Compose support in Android Studio Arctic Fox, here.

Sharing our roadmap for Compose

Adopting any new framework requires evaluation, especially something as far reaching as a new UI Toolkit. To help you to make an informed decision whether it’s the right time for you we’re publishing a public roadmap to share our plans to continue to build out Jetpack Compose.





Learning Compose

To help you get composing, we’ve prepared an extensive set of resources for you and your team:


There’s a lot to learn! The Jetpack Compose Pathway provides a step-by-step journey through key codelabs, videos and docs to help guide you.

Enjoy composing!

We really believe that Jetpack Compose is a huge leap forward, making it so much faster and easier to build great UIs; we can’t wait to see what you build with it. Now that Compose is stable at 1.0, it’s time to get started; there’s nothing better than getting right to the code. Happy Composing!

Build sophisticated search features with AppSearch

Posted by Dan Saadati, Software Engineer, and Hanaa ElAzizi, Technical Program Manager

Introducing AppSearch in Jetpack, now available in Alpha. AppSearch is an on-device search library which provides high performance and feature-rich full-text search functionality.

With AppSearch, your application can:

  • Offer offline search capabilities as AppSearch data lives completely on-device.
  • Have lower latency for indexing and querying over large data sets compared to SQLite, due to lower I/O use.
  • Provide relevant search results with built-in scoring strategies, such as BM25F.
  • Provide multi-language support for text search.
  • Issue a single query to retrieve data of multiple data types compared to issuing one query per data type in SQLite.

In AppSearch, you need to create a database to manage structured data, called “documents”. You then define what the structure looks like using “schema types”. For instance, you can model a message as a schema type with properties such as subject, body, and sender.

Documents that are added to your database can be queried over. Querying for “body:fruit” will retrieve all documents with the term “fruit” in the “body” of the Message.

Diagram illustrating the indexing of grocery list items in AppSearch, and searching for those items later

Diagram illustrating indexing and searching within AppSearch

To showcase how an application might integrate AppSearch, take this example of a grocery list application. Users can add grocery items to their list to refer to when they’re out shopping. Since AppSearch offers multi-language support by default, users can also include specialty ingredients for their global recipes. Users add an item by typing in the name and selecting the store and category it belongs to. The user can search by item name and select filters for store or category. AppSearch will return matching results for the application to display.

Ready to dive into using AppSearch to enrich your app’s search functionality? Check out the AppSearch guide and start using it in your app.

Help us make the library better: give us feedback on things you like, and issues or features you would like to see. If you find a bug or issue, feel free to file an issue.

What’s new in Jetpack

Posted by Florina Muntenescu, Android Developer Advocate

what's new in jetpack image

Android Jetpack is a suite of libraries, tools, and guidance to help developers follow best practices, reduce boilerplate code, and write code that works consistently across Android versions and devices. Today, 84% of the top 1000 apps on Google Play rely on Jetpack.

Here’s a round-up of the latest updates in Jetpack - an extended version of our What’s new in Jetpack talk!

New in Stable

CameraX

The CameraX library provides a unified API surface for accessing camera functionality across OS versions, including device-specific compatibility fixes and workarounds. Some of the latest improvements to the library address common feature requests, including support for adjusting exposure compensation and access to more detailed information about camera state and features. Additionally, camera settings like FPS range can now be changed via Camera2Interop while the camera is running. The library also brings support for the latest device and OS features, including high-dynamic-range preview, zoom ratio controls, and support for Android’s Do Not Disturb mode. Perhaps most importantly, though, the library has continued to address performance, resulting in faster image capture and faster initialization, especially on older devices.

Hilt

Hilt is Jetpack’s recommended dependency injection solution built on top of Dagger. As part of the transition to stable, Hilt’s ViewModel support has moved up into the core Hilt Android APIs and SavedStateHandle has been added as a default dependency available in the ViewModelComponent. Also, Hilt is now integrated with Navigation and Compose: you can obtain an annotated Hilt ViewModel that is scoped to a destination or the navigation graph itself. Developers have already started using Hilt in their apps. Read about their experience in this blog post.

Paging 3.0

The Paging library allows you to load and display small chunks of data to improve

network and system resource consumption. This release features a complete rewrite in Kotlin with first-class support for coroutines and Flow, asynchronous loading with RxJava and Guava primitives, and overall improvements to the repository and presentation layers.

The 3.0 release is a substantial improvement in usability over Paging 2, and the rewrite was planned with partial and staged migrations in mind so that developers can transition on their own schedules. Check out the Paging 3.0 documentation and the Paging 3.0 codelab for details and hands-on experience.

ConstraintLayout and MotionLayout

ConstraintLayout, Jetpack’s flexible system for designing layouts, and MotionLayout, an API aimed at managing motion and widget animation, are now stable. MotionLayout now includes support for foldable devices, image filters, and motion effects. To find out more about what’s new in design tools, check out this Google I/O talk.

Security Crypto

The Security Crypto library allows you to safely and easily encrypt files and SharedPreferences. To encrypt SharedPreferences, create an EncryptedSharedPreferences object with the appropriate key and scheme and then use it like a standard SharedPreferences object.

val prefs: SharedPreferences = EncryptedSharedPreferences.create(
        context,
        "prefs_file_name",
        mainKey,
        prefKeyEncryptionScheme = AES256_SIV,
        prefValueEncryptionScheme = AES256_GCM,
)
// Use the resulting SharedPreferences object as usual.
prefs.edit()
    .putBoolean("show_completed", true)
    .apply()
Fragment

Over the past year, the Fragment library has undergone a major effort to clean up its internal implementation and reduce undocumented behavior, making it easier for developers to follow best practices in their apps and write reliable tests. This lays the groundwork for future improvements to the library, like supporting multiple back stacks in Navigation, and it may require some work to accommodate strict enforcement of API contracts. In practice, you should pay careful attention to your tests after updating the library. Check out the Fragment release notes to see specific cases to watch out for.

Recent releases have also introduced ActivityResult integration, making it possible to register for Activity results from a fragment. Fragment has also added a new FragmentOnAttachListener interface to replace the less-flexible onAttachFragment method. Existing code that overrides this method in Fragment or FragmentActivity will still work, but we’ve deprecated onAttachFragment to help prevent new code from accidentally adopting a less-flexible approach.

// Obtain the fragment manager. May be a childFragmentManager,
// if in a fragment, to observe child attachment.
val fm = supportFragmentManager

val listener = FragmentOnAttachListener {
    fragmentManager, fragment ->
  // Respond to the fragment being attached.
}

fm.addFragmentOnAttachListener(listener)

New in Beta

Once a library is feature complete it moves to Beta for stabilization. At this moment, the APIs change only in response to critical issues or community feedback.

DataStore

DataStore provides a robust data storage solution that addresses the shortcomings of SharedPreferences while maintaining a simple, highly usable API surface. DataStore brings support for best practices like Kotlin coroutines with Flow and RxJava. DataStore allows you to store key-value pairs, via Preference DataStore or typed objects backed by protocol buffers, via Proto DataStore. You can also plug in your own serialization solution, like Kotlin Serialization.

New in Alpha

Alpha libraries are libraries under active development—APIs may be added, changed, or removed, but what’s in the library is tested and should be highly functional.

AppSearch

AppSearch is a new on-device search library which provides high performance and feature-rich full-text search functionality. Compared to SQLite, AppSearch supports multiple world languages, simplifies ranking query results, and offers lower latency for indexing and searching over large datasets.

AppSearch 1.0.0-alpha01 is released with LocalStorage support, which allows your application to manage structured data, called “documents”, and then query over it. Your application defines what the structure looks like using “schema types”. For instance, you can model a Message as a schema type with data such as subject, body, and sender.

Use builders to create documents of a schema type and then add them to storage. Querying for “body:fruit” will retrieve all documents with the term “fruit” in the body of the Message.

In Android S, AppSearch will also offer PlatformStorage so you can share your application’s data with other applications securely, and reduce your application’s binary size by not having to link additional native libraries. This is currently not available in Jetpack because the library doesn’t target the Android S SDK yet.

Centralized storage on Android S+ for integrating into device-wide search

Centralized storage on Android S+ for integrating into device-wide search

Room

Room is the recommended data persistence layer, providing increased usability and safety over the platform.

Room 2.4.0-alpha brings support for auto-migrations. When your database schema changes, you now declare an @AutoMigration and indicate from which version to which version you want to migrate, and Room generates the migrations for you. For more complex migrations, you can still use the Migration class:

@Database(
-   version = 1,
+   version = 2,
    entities = { Doggos.class },
+   autoMigrations = {
+         @AutoMigration (from = 1, to = 2)
+     }
  )
public abstract class DoggosDatabase extends RoomDatabase { }

Room 2.3.0 stable version brings experimental support for Kotlin Symbol Processing which, in our benchmarks of Kotlin code showed a 2x speed improvement over KAPT, as well as built-in support for enums and RxJava3.

Room has also introduced a QueryCallback class—which provides a callback when SQLite statements are executed, to simplify tasks like logging—as well as the new @ProvidedTypeConverter annotation, which allows more flexibility when creating type converters.

WorkManager

The WorkManager library—Android’s recommended way to schedule deferrable, asynchronous tasks that run even if the app exits or the device restarts—has made improvements to reliability with task reconciliation, ensuring all tasks are executed, and a variety of workarounds for specific Android OS versions.

The latest versions of WorkManager feature improved support for multi-process apps, including performance benefits from unifying work request scheduling to a single process and limiting database growth when scheduling many requests.

Version 2.7—now in alpha, which is targeted to the Android S SDK—provides additional support for the platform’s new foreground restrictions. See the Effective Background Tasks on Android talk for more details.

The Background Tasks Inspector is available in Android Studio Arctic Fox, allowing you to easily view and debug WorkManager jobs when using the latest versions of the library:

background tasts inspector

Background Tasks Inspector

Navigation

The Navigation library, Jetpack’s framework for moving between destinations in an app, now provides support for multiple backstacks and simplifies cases where destinations sit at the same depth, such as a bottom navigation bar.

Macrobenchmark

The Macrobenchmark library extends Jetpack’s benchmarking coverage to app startup and integrated behaviors like scrolling performance. The library can be used remotely to track metrics in continuous integration testing or locally with profiling results viewable from Android Studio. Check out the Google I/O talk on all the details:

For developers who’d like to integrate more closely with Google Assistant, the Google Shortcuts library provides a way to expose actions to Google Assistant and other Google Services through the existing ShortcutInfo class.

You can send up to fifteen shortcuts at a time through the ShortcutManager to be shown on Google Assistant, among other services, making them available for voice and other interactions.

To implement this, define a shortcut with an Intent and a capability binding; this binding provides semantically-meaningful information that will help Google services figure out the best way to surface it to users.

// expose a "Cappuccino" action to Google Assistant and other services
ShortcutInfoCompat siCompat =
  ShortcutInfoCompat.Builder(ctx, "id_cappuccino")
    .setShortLabel("Cappuccino")
    .setIntent(Intent(ctx, OrderCappuccino::class.java))
    .addCapabilityBinding(
        "actions.intent.ORDER_MENU_ITEM",
        "menuItem.name",
        asList("cappuccino")
    )
    .build()

ShortcutManagerCompat.pushDynamicShortcut(ctx, siCompat)
EmojiCompat

All user-generated content in your app contains 🎉, and supporting modern emoji is a key part of making your app ✨! The EmojiCompat library, which supports modern emoji on API 19 and higher, has moved to a new artifact :emoji2:emoji2, which replaces the previous :emoji:emoji artifact. The new emoji2 library adds 🪄 automatic configuration using the AppStartup library (you don't have to add any code 👩🏿‍💻 to display 🐻‍❄️)!

AppCompat adds emoji2 starting with AppCompat 1.4. If your app uses AppCompat, users will see modern emoji ⭐ without any further configuration. Apps that aren't using AppCompat can add :emoji2:emoji2-views. For custom TextViews, you can support modern emoji by using the helpers in :emoji2:emoji2-views-helpers or by subclassing AppCompat views.

Jetpack Compose

Jetpack Compose is Android’s modern toolkit for building native UI. It simplifies and accelerates UI development on Android. Jetpack Compose is currently in beta, and planned to go stable in July. Many of the libraries listed here, as well as others that you might already be using, have introduced features specifically for integration with Jetpack Compose. Ranging from Activity to ViewModel, Navigation, or Hilt, all of these libraries can make adopting Compose in your app smoother. Find out more about about how to use them from this Google I/O talk:

Form factors

Jetpack makes it easier to work with different form factors, including foldables, large screen devices, and Wear devices. We've introduced new guidelines for large screen development along with improvements to Jetpack libraries such as WindowManager and SlidingPaneLayout. Read all the details in this blog post.

Conclusion

This was a (relatively) quick overview of what’s new in Jetpack. Check out the AndroidX release notes for all the update details of each library and the Google I/O talks for more information on some of them.