Tag Archives: Jetpack Compose

Google Drive cut code and development time in half with Jetpack Compose and new architecture

Posted by Nick Butcher – Product Manager for Jetpack Compose, and Florina Muntenescu – Developer Relations Engineer

As one of the world’s most popular cloud-based storage services, Google Drive lets people do more than just store their files online. With Drive, users can synchronize, share, search, edit, and even pin specified files and content for safe and secure offline use.

Recently, Drive’s developers revamped the application’s home screen to provide a more seamless experience across devices, matching updates made to Google Drive’s web version. However, the app’s previous architecture and codebase would’ve prevented the team from completing the updates in a timely manner.

Instead of struggling with the app’s previous tech stack to implement the update, the Drive team rebuilt the home page from the ground up using Android’s recommended architecture and Jetpack Compose, Android’s modern declarative toolkit for creating native UI.

Compose, combined with architecture improvements, cut our development time nearly in half.” — Dale Hawkins, Senior software engineer and tech lead at Google Drive

Experimenting with Kotlin and Compose

The Drive team experimented with Kotlin — which the Compose toolkit is built with — for several months before planning the app’s home screen rebuild. Drive’s developers liked Kotlin’s improved syntax and null enforcement, making it easier to produce code.

“We had been using RxJava, but started looking into replacing that with coroutines,” said Dale Hawkins, the features team lead for Google Drive. “This led to a more natural alignment between coroutines and Jetpack Compose. After a deep dive into Compose, we came away with a clear understanding of how Compose has numerous benefits over the Views-based approach.”

Following the Kotlin exploration, Dale experimented with Jetpack Compose. “I was pleased with how easy it was to build the UI using Compose. So I continued the experiment after that week,” said Dale. “I eventually rewrote the feature using Compose.”

Using Compose

Shortly after experimenting with Jetpack Compose, the Drive team decided to use it to completely rebuild the app’s home screen UI.

“We wanted to make some major changes to match the ones being done for the web version, but that project had a several-month head start. We wanted to release the Android version shortly after the web changes went live to ensure our users have a seamless Google Drive experience across devices,” said Dale.

The Drive team's experimentation and testing with Jetpack Compose showed that the new toolkit was powerful and reliable and that it would enable them to move faster. With this in mind, the Drive team decided to step away from their old codebase and embrace Jetpack Compose for the app’s home screen update. Not only would it be quicker and easier, but it would also better prepare the team to easily make future UI changes.

Using Android’s guidance for architecture

Before going all-in with Jetpack Compose, Drive developers wanted to restructure the application by implementing a completely new app architecture. Drive developers followed Android’s official architecture guidance to apply structural changes, paving the way for the new Kotlin codebase.

“The recommended architecture reinforces good separation between layers,” said Quintin Knudsen, an Android engineer for Google Drive. “We work in a highly dynamic environment and need to be able to adjust to any app changes. Using well-defined and independent layers helps isolate any changes or UI requirements. The recommendations from Android offered sound ways to structure the layers.” With a clear separation between the app’s data and UI layers, developers could work in parallel to significantly speed up testing and development.

Drive developers also relied on Mappers and UseCases when creating the new architecture. These patterns allowed them to create flexible code that is easier to manage. They also exposed flows from their ViewModels to make the UI respond immediately to any data changes, making it much simpler to implement and understand UI updates.

Less code, faster development

With the app’s newly improved architecture and Jetpack Compose, the Drive team was able to develop the app’s new home screen in less than half the time that they expected. They also implemented the new code and finished quality assurance testing nearly seven weeks ahead of schedule.

“Thanks to Compose, we had the groundwork done within a couple of weeks. We delivered a great implementation over a month ahead of schedule, and it’s been praised by product, UX, and even other engineering teams,” said Dale.

Despite having fewer features, the original home screen required over 12,000 lines of code. The new Compose-based home screen has many new features and only required 5,100 lines of code—a 57% reduction. Having less code makes it much easier for developers to maintain the app and implement any updates.

Testing the new UI in Jetpack Compose also required significantly less code. Before Compose, Drive developers used roughly 9,000 lines of code to test about 62% of the UI. With Compose, it took only 2,200 lines to test over 80% of the new UI.

The original home screen required over 12,000 lines of code. The Compose-based home screen only required 5,100 lines of code. That’s a 57% reduction.” — Dale Hawkins, Senior software engineer and tech lead at Google Drive

Looking forward

A new and improved app architecture paired with Jetpack Compose allowed Drive developers to rebuild the app’s home screen UI faster and easier than they could’ve imagined. The Drive team plans to expand its use of Compose within the application for things like supporting large dynamic displays and text resizing.

“As we work on new projects, we’re taking the opportunity to update older UI code to make use of our new architecture and Compose. The new code will be objectively better and features will be easier to write, test, and maintain,” said Dale.

Get started

Improve app architecture using Android’s official architecture guidance and optimize your UI development with Jetpack Compose.

#TheAndroidShow: the latest from MWC, Gemini Nano, Android 15 and more!

Posted by Anirudh Dewani, Director of Android Developer Relations


Last week, Android device makers released a slew of new devices, and today we’re unpacking what that means for developers, as well as the latest in Gemini Nano, Android 15, Jetpack Compose and more, in another episode of our quarterly show, #TheAndroidShow:

The lastest wearables and foldables – get building!

Android device makers unveiled their latest wearables and foldables last week at Mobile World Congress, and we were on the ground in Barcelona taking a look at those new devices and how you can get started building on top of them. A few of our favorites:

    • Xiaomi Watch 2,the latest smart watch from the Xiaomi team. This device is powered by Wear OS by Google and provides upgraded camera, fitness, and sleep experiences to allow users to get the most from their device.
    • PORSCHE DESIGN HONOR Magic V2 RSR, the world’s thinnest inward foldable smartphone. This is the latest foldable for Android and was designed with the user experience at the forefront, including human-centric eye comfort technology.

Compose is an amazing way to build apps for your users across form factors. Compose for Wear OS and the upcoming adaptive layouts for large screens help devs bring their apps to life with less code, powerful tools, and intuitive APIs. Check out the Wear OS and Large Screen galleries, where you can find UX inspiration and design guidance tailored to your type of app.




Behind the scenes, with Gemini Nano and AICore

With all of the excitement around generative AI, it could be daunting to know where to start. So in today’s show, we’re taking you behind the scenes with Gemini Nano, Google’s most efficient model built for on-device tasks, and AICore, Android’s system service for on-device foundation models. And we’re spotlighting how the team that builds the Recorder app used Gemini Nano to help summarize users’ voice memos on-device and with privacy in mind. And here’s the best part: the team built the feature in a short time with only a small number of engineers.




Now in Android

We celebrated the 100th episode of Now in Android, covering the latest developer news, including:




And that’s a wrap on another episode of our quarterly show, #TheAndroidShow. But the conversation continues on YouTube, X and LinkedIn: tell us your favorite part, or what you’d like us to dive into next time on our quarterly episode. And before we sign off, you can watch the full playlist, with the latest in Android developer news, here.

New goodies from Android, Wearables at Mobile World Congress + tune in to a new episode of #TheAndroidShow next week!

Posted by Anirudh Dewani, Director of Android Developer Relations

Earlier today, at Mobile World Congress (MWC), an annual conference showcasing the latest in mobile, Android and our partners unveiled a range of new goodies, including new wearables, foldables, as well as a number of new features for Android users. Keep reading below to see how you, as developers, can take advantage of these new features and devices that are being released. And in just over a week, on Thursday March 7 at 10AM PT, we’ll be kicking off another episode of #TheAndroidShow, our quarterly live show on YouTube and on developer.android.com, where we’ll dive more into these topics.


Meet the new watch from OnePlus and how we’re boosting power with the Wear OS hybrid interface

Wearables are on display across MWC this week, and one of our favorites is OnePlus Watch 2, powered with the latest version of Wear OS (Wear OS 4). As part of our ongoing work to improve the Wear OS by Google user experience, we’ve made fundamental changes to the platform and substantially expanded the capabilities of the Wear OS hybrid interface that improve two key areas: power and performance. As a developer, you can leverage existing Wear OS APIs to get underneath optimizations without any added effort – no code changes required! You can read more about the updates here.

Images of three people wearing the OnePlus Watch 2

A few new features for Android users

Google released 9 new features Android users can take advantage of across Google apps, you can read more about those features here. For developers, we wanted to highlight a few ways you can take advantage of this news across experiences you build into your apps:

    • More places for users to see their Health Connect data, now in the Fitbit app: With permission from your users, Health Connect is a central way to connect and sync their favorite health and fitness apps, see all their data in one place, and stay in control of their privacy. By setting up Health Connect in the Fitbit mobile app for Android, users will have an overview of their health and fitness data from across their apps in one place. You can join developers like Peloton, ŌURA, and Lifesum who are using Health Connect to provide their users with deeper health and fitness insights, get started now!
Image that reads 'New updates on Android' with pictures of a smart watch, laptop, and Android Auto

A new episode of #TheAndroidShow, live on March 7 at 10AM PT. Send us your #AskAndroid questions now!

You can join us on March 7 at 10AM PT for a new episode of #TheAndroidShow. In this quarterly show, we’ll unpack the latest Android foldables and large screens for you to get building on, plus a behind-the-scenes on Gemini Nano and AICore.

We’ll have a live #AskAndroid Q&A with the team about building Android; you can ask us about building excellent apps across devices, Android 15, Compose, Gemini and more, using #AskAndroid on X or on YouTube. Our experts are ready to answer your questions live!

#TheAndroidShow: March 7 at 10AM PT, broadcast live on YouTube and d.android.com/events/show!

What’s new in the Jetpack Compose January ’24 release

Posted by Ben Trengrove, Android Developer Relations Engineer

Today, as part of the Compose January ‘24 Bill of Materials, we’re releasing version 1.6 of Jetpack Compose, Android's modern, native UI toolkit that is used by apps such as Threads, Reddit, and Dropbox. This release largely focuses on performance improvements, as we continue to migrate modifiers and improve the efficiency of major parts of our API.

To use today’s release, upgrade your Compose BOM version to 2024.01.01

implementation platform('androidx.compose:compose-bom:2024.01.01')

Performance

Performance continues to be our top priority, and this release of Compose has major performance improvements across the board. We are seeing an additional ~20% improvement in scroll performance and ~12% improvement to startup time in our benchmarks, and this is on top of the improvements from the August ‘23 release. As with that release, most apps will see these benefits just by upgrading to the latest version, with no other code changes needed.

The improvement to scroll performance and startup time comes from our continued focus on memory allocations and lazy initialization, to ensure the framework is only doing work when it has to. These improvements can be seen across all APIs in Compose, especially in text, clickable, Lazy lists, and graphics APIs, including vectors, and were made possible in part by the Modifier.Node refactor work that has been ongoing for multiple releases.

There is also new guidance for you to create your own custom modifiers with Modifier.Node.

Configuring the stability of external classes

Compose compiler 1.5.5 introduces a new compiler option to provide a configuration file for what your app considers stable. This option allows you to mark any class as stable, including your own modules, external library classes, and standard library classes, without having to modify these modules or wrap them in a stable wrapper class. Note that the standard stability contract applies; this is just another convenient method to let the Compose compiler know what your app should consider stable. For more information on how to use stability configuration, see our documentation.

Generated code performance

The code generated by the Compose compiler plugin has also been improved. Small tweaks in this code can lead to large performance improvements due to the fact the code is generated in every composable function. The Compose compiler tracks Compose state objects to know which composables to recompose when there is a change of value; however, many state values are only read once, and some state values are never read at all but still change frequently! This update allows the compiler to skip the tracking when it is not needed.

Compose compiler 1.5.6 also enables “intrinsic remember” by default. This mode transforms remember at compile time to take into account information we already have about any parameters of a composable that are used as a key to remember. This speeds up the calculation of determining if a remembered expression needs reevaluating, but also means if you place a breakpoint inside the remember function during debugging, it may no longer be called, as the compiler has removed the usage of remember and replaced it with different code.

Composables not being skipped

We are also investing in making the code you write more performant, automatically. We want to optimize for the code you intuitively write, removing the need to dive deep into Compose internals to understand why your composable is recomposing when it shouldn’t.

This release of Compose adds support for an experimental mode we are calling “strong skipping mode”. Strong skipping mode relaxes some of the rules about which changes can skip recomposition, moving the balance towards what developers expect. With strong skipping mode enabled, composables with unstable parameters can also skip recomposition if the same instances of objects are passed in to its parameters. Additionally, strong skipping mode automatically remembers lambdas in composition that capture unstable values, in addition to the current default behavior of remembering lambdas with only stable captures. Strong skipping mode is currently experimental and disabled by default as we do not consider it ready for production usage yet. We are evaluating its effects before aiming to turn it on by default in Compose 1.7. See our guidance to experiment with strong skipping mode and help us find any issues.

Text

Changes to default font padding

This release now makes the includeFontPadding setting false by default. includeFontPadding is a legacy property that adds extra padding based on font metrics at the top of the first line and bottom of the last line of a text. Making this setting default to false brings the default text layout more in line with common design tools, making it easier to match the design specifications generated. Upon upgrading to the January ‘24 release, you may see small changes in your text layout and screenshot tests. For more information about this setting, see the Fixing Font Padding in Compose Text blog post and the developer documentation.

Line height with includeFontPadding as false on the left and true on the right.

Support for nonlinear font scaling

The January ‘24 release uses nonlinear font scaling for better text readability and accessibility. Nonlinear font scaling prevents large text elements on screen from scaling too large by applying a nonlinear scaling curve. This scaling strategy means that large text doesn't scale at the same rate as smaller text.

Drag and drop

Compose Foundation adds support for platform-level drag and drop, which allows for content to be dragged between apps on a device running in multi-window mode. The API is 100% compatible with the View APIs, which means a drag and drop started from a View can be dragged into Compose and vice versa. To use this API, see the code sample.

Moving image illustrating drag and drop feature

Additional features

Other features landed in this release include:

    • Support for LookaheadScope in Lazy lists.
    • Fixed composables that have been deactivated but kept alive for reuse in a Lazy list not being filtered by default from semantics trees.
    • Spline-based keyframes in animations.
    • Added support for selection by mouse, including text.

Get started!

We’re grateful for all of the bug reports and feature requests submitted to our issue tracker — they help us to improve Compose and build the APIs you need. Continue providing your feedback, and help us make Compose better!

Wondering what’s next? Check out our roadmap to see the features we’re currently thinking about and working on. We can’t wait to see what you build next!

Happy composing!

Meta built threads in only 5 months using Jetpack Compose

Posted by Yasmine Evjen – Product Manager, and Florina Muntenescu – Developer Relations Engineer

Following its release in July of 2023, Meta’s Threads became the most rapidly downloaded app ever with over 100 million downloads in its first week. Meta created the new text-based social media platform as a place to build connections and have meaningful conversations. To ensure the app was set up for success at its release and into the future, Threads developers used Jetpack Compose, Android’s modern declarative toolkit for building UI.

An easier way to build UI with Jetpack Compose

Threads is built on top of existing code from its sister app Instagram, which uses Views for its UI development. After positive reports from other Android developers about Compose, and following internal testing and an assessment of the toolkit’s benefits, Threads engineers opted to build the all-new app from scratch using Compose. By using Compose, the team could move faster and better prepare the app for any future updates.

“We decided Jetpack Compose would be our target UI framework going forward,” said Richard Zadorozny, a software engineer at Threads. “We wanted to build the new app UI from scratch using Compose because it would enable us to move faster than refactoring a large application like Instagram.”

Even though most of Threads’ engineers had no prior experience using Compose, they found it easy to get started and learn the new toolkit. With Compose, Threads engineers built and shipped the app in only five months. This greatly exceeded the team’s speed expectations for developing a high-quality Android application — especially of this complexity and scale. The team attributes much of this speed to the flexibility and decoupling Compose provided.

Compose helped Threads engineers streamline the development of new product features. The modular nature of the toolkit let Threads developers iterate on the app as it evolved and teed up the app’s architecture for future development. Compose also helped engineers build user-friendly features that adhered to Material Design guidelines.

Threads was built and shipped in five months, exceeding our speed expectations for building a high-quality Android app of this complexity and scale.”  — Richard Zadorozny, software engineer at Threads

Going all in with Compose

Threads engineers developed almost all of the app’s surfaces using Compose. In the end, they built over 90% of Threads using Compose, including the app’s activity feed, navigation, search, profiles, onboarding page, shared element transitions, media viewer, settings, and more.

While Compose did mostly everything Threads engineers needed it to, it was still easy for them to interoperate with Views as necessary. They used Views for Threads’ videos and the media picker that’s available when creating a new post.

Compose provides modern APIs that ship directly with an app. Because of this, Threads engineers spent less time worrying about backward compatibility, missing features, or differing functionality between different versions of Android. Instead, they could focus their energy on developing a high-quality application.

“Compose’s design encourages a modular, plug-in approach to development,” said Richard. “Modifiers make all sorts of functionality inherently reusable, so you no longer have to subclass complicated ViewGroups or lump all sorts of logic into one place.”

Moving image shows Jetpack Compose/Modifiers code appears on screen

The Threads team used Modifiers for the app’s custom click behaviors and its thread line illustration that appears on the left side of posts. Modifiers also allowed Threads developers to easily add the app’s branding to any elements and ensured they were properly aligned on-screen.

Threads engineers also ensured the app was ready for users across platforms at launch. That meant making sure Threads resizes to work on different devices, like large screens and foldables. The adaptive layouts Compose offers ensure an app responds properly to different screen sizes, orientations, and form factors. This made it easier for the Threads app to “just work” for configuration changes, according to Richard.

For developers who are building new apps, I would definitely recommend using Compose. Not only is it enjoyable… it sets your team up for success in the future.” — Richard Zadorozny, software engineer at Threads

Compose is the ‘future’ of Android UI

Compose offered Threads developers an easier way to design and create UI while preparing the app’s architecture for the future. With its intuitive composables and modern declarative framework, Compose made end-to-end development smooth and gave Threads developers confidence that updating the app would be easy.

Given the positive results the team saw with the release of Threads, Meta plans to expand its use of Compose to some of Instagram’s most important surfaces, like the app’s main feed.

“It’s reached a point where Jetpack Compose can do almost everything you’ll need, and its modular nature makes it easy to make most of the changes you would need to fill the gaps,” said Richard. “I believe Compose is the future of Android UI development, and it’s just fun!”

Get started

Optimize your UI development with Jetpack Compose.

#TheAndroidShow: Faster and easier to build excellent apps, across devices.

Posted by Anirudh Dewani, Director of Android Developer Relations

We just wrapped another episode of #TheAndroidShow; in the show, we covered the latest in Android development, including a look at the new Pixel watch and the world of wearables, gathered the team to demo tools and libraries to build for foldables, large screen devices, with Compose, Android 14, Studio Bot, and more. Take a look, and here’s a recap of some of the ways we’re helping make it faster and easier to build excellent apps, across devices:

Studio Bot: improving your productivity, through Generative AI

At Google I/O we gave you a preview of Studio Bot, an AI powered coding assistant that is tightly integrated into Android Studio, designed to make Android development faster and easier. Last month, Studio Bot expanded into over 170 countries, and today we’re adding even more functionality in the latest canary release to help you be more productive. AI code completion enables you to receive suggestions for more complex code completions, such as multiline code or even entire functions. You can also now add comments to your code, and document code with just a click using Studio Bot. We caught up with Jamal Eason to learn about the investments the team is working on, including our improvements in quality.

Faster and easier to build, with Jetpack Compose

Jetpack Compose gives you powerful and intuitive APIs, which make it faster and easier to build UIs. Since Google I/O, we’ve been working on improving performance across Compose to make it even more helpful. Developers around the world are taking advantage of Compose to help them rewrite screens, build new screens, or create new apps. For example, The Reddit team adopted Compose for their design system, which improved their code flexibility and reduced code duplication. They rewrote several features in Compose and their new tech stack, one of them being Reddit Recap, with beautiful animations. They were able to achieve feature parity with 44% less code when they rewrote it using Compose, saving engineering resources and time.

Build across devices, with large screens

Foldables and tablets are an important space - and the market for large screens is growing with Samsung announcing that half of their users are thinking of making a foldable their next phone. We’re continuing to build tools and libraries to make it easier to build for different device types, including device streaming and new drag and drop APIs in Compose. See how Zoom saw 2x higher user engagement and optimized their app for large screens, and get started with making your app work better across screen sizes and form factors.

The latest in wearables, with Wear OS 4 and Pixel Watch 2

Earlier this month, we saw the launch of Google Pixel Watch 2 - the first Google watch with all the capabilities of Wear OS 4! The latest version of Wear OS offers several capabilities that make it easier to develop exceptional wearable experiences, from Watch Face Format to enhanced tiles and more. Read more to discover the latest updates to Wear OS and how you can get started!

Making excellent, premium apps

Earlier this month, Android 14 started rolling out to users around the world. So there’s no better time to start optimizing your apps for the release and taking advantage of new features in Android 14 to help you build excellent experiences for your users using the best of Android, such as improved camera functionality with UltraHDR, seamless authentication with Credential Manager and enhanced widget development with Jetpack Glance. In the show, we saw how Snapchat used Camera2 Extension API to build camera features such as night mode, zoom, and tap-to-focus, enhancing their user’s experience capturing high-quality Snaps on Android devices, and also had a conversation with Dave Burke about Android 14 and more. Take a look!

Connecting with you at events around the world

This year, we're excited to bring the Android team and our Android Google Developer Expert friends to events around the world, you can learn more about it here. Later this month, the Android team will be at Droidcon London (October 26-27), bringing talks and hosting office hours around many exciting topics, and a panel of subject matter experts. Android GDEs will be speaking at 100+ DevFest events around the world, with special appearances from the Android team at DevFests in New York, the Bay Area, London, and Singapore among others. We look forward to connecting with thousands of you in person!


Missed the show? You can watch it here, or check out the full playlist here. This is your conversation with the broader Android community, and if you’ve got an idea for the next show, we’d love to hear it - send us a Tweet, or share a message in the comments. We can’t wait to hear from you!

What’s new in the Jetpack Compose August ’23 release

Posted by Ben Trengrove, Android Developer Relations Engineer

Today, as part of the Compose August ‘23 Bill of Materials, we’re releasing version 1.5 of Jetpack Compose, Android's modern, native UI toolkit that is used by apps such as Play Store, Dropbox, and Airbnb. This release largely focuses on performance improvements, as major parts of our modifier refactor we began in the October ‘22 release are now merged.

Performance

When we first released Compose 1.0 in 2021, we were focused on getting the API surface right to provide a solid foundation to build on. We wanted a powerful and expressive API that was easy to use and stable so that developers could confidently use it in production. As we continue to improve the API, performance is our top priority, and in the August ‘23 release, we have landed many performance improvements.

Modifier performance

Modifiers see large performance improvements, up to 80% improvement to composition time, in this release. The best part is that, thanks to our work getting the API surface right in the first release, most apps will see these benefits just by upgrading to the August ‘23 release.

We have a suite of benchmarks that are used to monitor for regressions and to inform our investments in improving performance. After the initial 1.0 release of Compose, we began focusing on where we could make improvements. The benchmarks showed that we were spending more time than anticipated materializing modifiers. Modifiers make up the vast majority of a composition tree and, as such, were the largest contributor to initial composition time in Compose. Refactoring modifiers to a more efficient design began under the hood in the October ‘22 release.

The October ‘22 release included new APIs and performance improvements in our lowest level module, Compose UI. Modifiers build on top of each other so we started migrating our low level modifiers in Compose Foundation in the next release, March ‘23. This included graphicsLayer, low level focus modifiers, padding, and offset. These low level modifiers are used by other highly utilized modifiers such as Clickable, and are also utilized by many framework Composables such as Text. Migrating modifiers in the March ‘23 release brought performance improvements to those components, but the real gains would come when we could migrate the higher level modifiers and composables themselves to the new modifier system.

In the August ‘23 release, we have begun migrating the Clickable modifier to the new modifier system, bringing substantial improvements to composition time, in some cases up to 80%. This is especially relevant in lazy lists that contain clickable elements such as buttons. Modifier.indication, used by Clickable, is still in the process of being migrated, so we anticipate further gains to come in future releases.

As part of this work, we identified a use case for composed modifiers that wasn’t covered in the original refactor and added a new API to create Modifier.Node elements that consume CompositionLocal instances.

We are now working on documentation to guide you through migrating your own modifiers to the new Modifier.Node API. To get started right away, you can reference the samples in our repository.

Learn more about the rationale behind the changes in the Compose Modifiers deep dive talk from Android Dev Summit ‘22.

Memory

This release includes a number of improvements in memory usage. We have taken a hard look at allocations happening across different Compose APIs and have reduced the total allocations in a number of areas, especially in the graphics stack and vector resource loading. This not only reduces the memory footprint of Compose, but also directly improves performance, as we spend less time allocating memory and reduce garbage collection.

In addition, we fixed a memory leak when using ComposeView, which will benefit all apps but especially those that use multi-activity architecture or large amounts of View/Compose interop.

Text

BasicText has moved to a new rendering system backed by the modifier work, which has brought an average of gain of 22% to initial composition time and up to a 70% gain in one benchmark of complex layouts involving text.

A number of Text APIs have also been stabilized, including:

Improvements and fixes for core features

We have also shipped new features and improvements in our core APIs as well as stabilizing some APIs:

  • LazyStaggeredGrid is now stable.
  • Added asComposePaint API to replace toComposePaint as the returned object wraps the original android.graphics.Paint.
  • Added IntermediateMeasurePolicy to support lookahead in SubcomposeLayout.
  • Added onInterceptKeyBeforeSoftKeyboard modifier to intercept key events before the soft keyboard.

Get started!

We’re grateful for all of the bug reports and feature requests submitted to our issue tracker — they help us to improve Compose and build the APIs you need. Continue providing your feedback, and help us make Compose better!

Wondering what’s next? Check out our roadmap to see the features we’re currently thinking about and working on. We can’t wait to see what you build next!

Happy composing!

Deep dive into Live Edit for Jetpack Compose UI

Posted by Alan Leung, Staff Software Engineer, Fabien Sanglard, Senior Software Engineer, Juan Sebastian Oviedo, Senior Product Manager
A closeup look into how the Android Studio team built Live Edit; a feature that accelerates the Compose development process by continuously updating the running application as code changes are made.

What’s Live Edit and how can it help me?

Live Edit introduces a new way to edit your app’s Jetpack Compose UI by instantly deploying code changes to the running application on a physical device or emulator. This means that you can make changes to your app’s UI and immediately see their effect on the running application, enabling you to iterate faster and be more productive in your development. Live Edit was recently released to the stable channel with Android Studio Giraffe and can be enabled in the Editor settings. Developers like Plex and Pocket Casts are already using Live Edit and it has accelerated their development process for Compose UI. It is also helping them in the process of migrating from XML views to Compose.


Moving image illustrating Live Edit in action on Android Studio Hedgehog
Live Edit in action on Android Studio Hedgehog

When should I use Live Edit?

Live Edit is a different feature from Compose Preview and Apply Changes. These features provide value in different ways:

Feature

Description

When should I use it?

Live Edit[Kotlin only, supports live recomposition] Make changes to your Compose app’s UI and immediately see their effect on the running application on an emulator or physical device. Quickly see the effect of updates to UX elements (such as modifier updates and animations) on the overall app experience while the application is running.
Compose Preview

[Compose only] Visualize Compose elements in the Design tab within Android Studio and see them automatically refresh as you make code changes. Preview individual Compose elements in one or many different configurations and states, such as dark theme, locales, and font scale.
Apply Changes

Deploy code and resource updates to a running app without restarting it—and, in some cases, without restarting the current activity. Update code and resources in a non-Compose app without having to redeploy it to an emulator or physical device.

How does it work?

At a high level, Live Edit does the following:

  1. Detects source code changes.
  2. Compiles classes that were updated.
  3. Pushes new classes to the device.
  4. Adds a hook in each class method bytecode to redirect calls to the new bytecode.
  5. Edits the app classpath to ensure changes persist even if the app is restarted.

Illustration of Live Edit architechture
Live Edit architecture

Keystroke detection

This step is handled via the Intellij IDEA Program Structure Interface (PSI) tree. Listeners allow LE to detect the moment a developer makes a change in the Android Studio editor.

Compilation

Fundamentally, Live Edit still relies on the Kotlin compiler to generate code for each incremental change.

Our goal was to create a system where there is less than 250ms latency between the last keystroke and the moment the recomposition happens on the device. Doing a typical incremental build or invoking an external compiler in a traditional sense would not achieve our performance requirement. Instead, Live Edit leverages Android Studio’s tight integration with the Kotlin compiler.

On the highest level, the Kotlin compiler’s compilation can be divided into two stages.

  • Analysis
  • Code generation

The analysis performed as the first step is not entirely restricted to a build process. In fact, the same step is frequently done outside the build system as part of an IDE. From basic syntax checking to auto-complete suggestions, the IDE is constantly performing the same analysis (Step 1 of Diagram 1) and caching the result to provide Kotlin- and Compose-specific functionality to the developer. Our experiment shows that the majority of the compilation time is spent in the analysis stage during build. Live Edit uses that information to invoke the Compose compiler. This allows compilation to happen within 200ms using typical laptops used by developers. Live Edit further optimizes the code generation process and focuses solely on generating code that is only necessary to update the application.

The result is a plain .class file (not a .dex file) that is passed to the next step in the pipeline, desugaring.

How to desugar

When Android app source code is processed by the build system, it is usually “desugared” after it is compiled. This transformation step lets an app run on a set of Android versions devoid of syntactic sugar support and recent API features. This allows developers to use new APIs in their app while still making it available to devices that run older versions of Android.

There are two kinds of desugaring, known as language desugaring and library desugaring. Both of these transformations are performed by R8. To make sure the injected bytecode will match what is currently running on the device, Live Edit must make sure each class file is desugared in a way that is compatible with the desugaring done by the build system.

Language desugaring:

This type of bytecode rewrite aims to provide newer language features for lower targeted API level devices. The goal is to support language features such as the default interface method, lambda expression, method reference, and so on, allowing support down to the min API level. This value is extracted from the .apk file's DEX files using markers left in there by R8.

API desugaring:

Also known as library desugaring, this form of desugaring aims to support JAVA SDK methods and classes. This is configured by a JSON file. Among other things, method call sites are rewritten to target functions located in the desugar library (which is also embedded in the app, in a DEX file). To perform this step, Gradle collaborates with Live Edit by providing the JSON file used during library desugaring.

Function trampoline

To facilitate a rapid “per-key-stroke” speed update to a running application, we decided to not constantly utilize the JVMTI codeswap ability of the Android Runtime (ART) for every single edit. Instead, JVMTI is only used once to perform a code swap that installs trampolines onto a subset of methods within the soon-to-be modified classes inside the VMs. Utilizing something we called the “Primer” (Step 3 of Diagram 1), invocation of the methods is redirected to a specialized interpreter. When the application no longer sees updates for a period of time, Live Edit will replace the code with traditional DEX code for performance benefits of ART. This saves developers time by immediately updating the running application as code changes are made.

Illustration of Function trampoline process
Function trampoline process

How code is interpreted

Live Edit compiles code on the fly. The resulting .class files are pushed, trampolined (as previously described), and then interpreted on the device. This interpretation is performed by the LiveEditInterpreter. The interpreter is not a full VM inside ART. It is a Frame interpreter built on top of ASM Frame. ASM Frame handles the low level logistics such as the stack/local variables's push/load, but it needs an Interpreter to actually execute opcode. This is what the OpcodeInterpreter is for.

Flow chart of Live Edit interpretation
Live Edit interpretation flow

Live Edit Interpreter is a simple loop which drives ASM/Interpreter opcodes interpretation.

Some JVM instructions cannot be implemented using a pure Java interpreter (in particular invokeSpecial and monitorEnter/Exit are problematic). For these, Live Edit uses JNI.

Dealing with lambdas

Lambdas are handled in a different manner because changes to lambda captures can result in changes in VM classes that are different in many method signatures. Instead, new lambda-related updates are sent to the running device and loaded as new classes instead of redefining any existing loaded classes as described in the previous section.

How does recomposition work?

Developers wanted a seamless and frictionless new approach to program Android applications. A key part of the Live Edit experience is the ability to see the application updated while the developer continuously writes code, without having to explicitly trigger a re-run with a button press. We needed a UI framework that has the ability to listen to model changes within the application and perform optimal redraws accordingly. Luckily, Jetpack Compose fits this task perfectly. With Live Edit, we added an extra dimension to the reactive programming paradigm where the framework also observes changes to the functions’ code.

To facilitate code modification monitoring, the Jetpack Compose compiler supplies Android Studio with a mapping of function elements to a set of recomposition group keys. The attached JVMTI agent invalidates the Compose state of a changed function in an asynchronous manner and the Compose runtime performs recomposition on Composables that are invalidated.

How we handle runtime errors during recomposition

Moving image of Live edit handling a runtime error
Live Edit handling a runtime error

While the concept of a continuously updating application is rather exhilarating, our field studies showed that sometimes when developers are writing code, the program can be in an incomplete state where updating and re-executing certain functions would lead to undesirable results. Besides the automatic mode where updates are happening almost continuously, we have introduced two manual modes for the developer who wants a bit more control on when the application gets updated after new code is detected.

Even with that in mind, we want to make sure common issues caused by executing incomplete functions do not cause the application to terminate prematurely. Cases where a loop’s exit condition is still being written are detected by Live Edit to avoid an infinite loop within the program. Also, if a Live Edit update triggers recomposition and causes a runtime exception to be thrown, the Compose runtime will catch such an exception and recompose using the last known good state.

Consider the following piece of code:

var x = y / 10

Suppose the developer would like to change 10 to 50 by deleting the character 1 and inserting character 5 after. Android Studio could potentially update the application before the 5 is inserted and thus create a division-by-zero ArithmeticException. However, with the added error handling mentioned, the application would simply revert to “y / 10” until further updates are done in the editor.

What’s coming?

The Android Studio team believes Live Edit will change how UI code is written in a positive way and we are committed to continuously improve the Live Edit development experience. We are working on expanding the types of edits developers can perform. Furthermore, future versions of Live Edit will eliminate the need to invalidate the whole application during certain scenarios.

Additionally, PSI event detection comes with limitations such as when the user edits import statements. To solve this problem, future versions of Live Edit will rely on .class diffing to detect changes. Lastly, the full persisting functionality isn't currently available. Future versions of Live Edit will allow the application to be restarted outside of Android Studio and retain the Live Edit changes.

Get started with Live Edit

Live Edit is ready to be used in production and we hope it can greatly improve your experience developing for Android, especially for UI-heavy iterations. We would love to hear more about your interesting use cases, best practices and bug reports and suggestions.

Java is a trademark or registered trademark of Oracle and/or its affiliates.

Dropbox rebuilt its search experience 40% faster with Jetpack Compose

Posted by the Android team

Available in 180 countries and with over 1 billion downloads on Google Play, Dropbox is one of the world’s most popular file sharing and cloud storage services. Dropbox is on a mission to design a more enlightened way of working, keeping life organized and work moving. Recently that meant Jetpack Compose , Android’s modern declarative toolkit for creating native UI.

Quote card with headshot of Ryan Harter, smiling. Quote text reads, 'With first class-support for design systems in Compose, we felt it would be easier to create a cohesive experience across our app that fit the Dropbox branding.'- Ryan Harter, Staff Android Engineer at Dropbox

A smarter, faster way to build UI

Since adopting Compose, Dropbox developers have rewritten many features for the app, including its home screen, file preview, and search experiences. Dropbox’s search experience was completely rebuilt in just a few weeks, which was 40% less time than expected and less than half the time it took them to build the same feature for iOS.

The team being able to work faster was a direct result of how simple it was for them to use Compose. Since rebuilding the search experience, Dropbox developers have seen a 13% increase in successful search sessions —a key metric for the team.

Compose helped Dropbox developers move quickly, letting them easily build complex, custom UIs with the toolkit’s basic building blocks and utilities. “Support for multiple previews, with different configurations or data, allows us to consider different variations of components as we build them instead of as an afterthought,” said Ryan Harter, staff Android engineer at Dropbox.

The Dropbox team also built a new design system on top of Android’s MaterialTheme, which the engineers accomplished by following Compose best practices. Creating the new design system on top of Android’s MaterialTheme minimized the time it took for Dropbox developers to lay the app’s foundation, allowing them to build new features with Compose while maintaining a look and feel that’s consistent with Dropbox’s branding.

Compatibility with Views made trying Compose easy

Dropbox developers were also swayed to use Compose thanks to its interoperability with Views and were impressed by how easy it was to develop in tandem with both toolkits. The Dropbox team was able to support classic Views libraries and plugins within the app while creating new UI components using Compose. Because of this, Dropbox developers could gradually migrate the app to Compose instead of completely overhauling the app.

“Interoperability with Compose allowed us to move forward with the toolkit, even when we needed to interact with Views in certain workflows such as ExoPlayer and PDF document views,” continued Ryan. “You can start with a smaller component and experience the benefits and improved speed without committing to rewriting your entire app. It’s clear that Compose was designed with the intention that users don’t need to perform an all-or-nothing migration.”

Improved testing and experimentation

During their rewrites, Dropbox engineers found that Compose made developing easier and enabled more efficient testing. “Compose, together with Android Studio’s preview support, has allowed us to iterate on features faster by reducing the length of the feedback cycle while developing screens,” continued Ryan.

The fast feedback cycle and interactive previews from Compose allowed the Dropbox team to experiment with UX quickly and test any assumptions they had about the updates, which made it easier to release features.

“If questions came up about performance or use of an approach, we went into Android Studio and used the interactive previews to test and measure results so we’d have more answers and fewer assumptions,” said Alison Wyllie, a senior software engineer at Dropbox. “And the fast feedback cycle and interactive previews that come with Compose have allowed us to experiment quickly with UX and test our assumptions, allowing us to get features into users’ hands faster.”

Jetpack Compose’s push toward a unidirectional data flow (UDF) also helped Dropbox engineers while testing and debugging. Combining UDF with Compose testing libraries and the toolkit’s declarative approach to creating UI made the Dropbox team confident that the app’s features were stable and bug free because they could fully test them before release.

Quote card with headshot of Alison Wyllie, smiling. Quote text reads, 'What used to take hundreds of lines of code can now be done in ten, saving time and making code much easier to understand and maintain'- Alison Wyllie, Senior Software Engineer at Dropbox

Continuing improvements with Jetpack Compose

Dropbox’s engineers were impressed by the ease and speed with which they could iterate and get feedback using Compose. With interactive and on-device previews, Compose allows for experimentation and development in ways that weren’t previously possible for the team at Dropbox. The Dropbox team plans to continue building the app’s design system using Compose and expects most new features to be written with the toolkit.

“Compose gave us a fresh start with a lot of key areas that have historically been difficult for Android engineers. I’m very excited to see what new functionality Google and the open source community will create next,” said Allison.

Get started

Optimize your UI development with Jetpack Compose.

Jetpack Compose Buttons for Google Pay and Google Wallet

Posted by Stephen McDonald, Developer Programs Engineer

We recently released a new Google Pay button view on Android which brings a range of new features, such as the latest Material 3 design principles, dark and light themed versions, and other new customization capabilities.

Image of the new Google Pay button view for Android
Figure 1: The new Google Pay button view for Android can be customized to make it more consistent with your checkout experience.


Jetpack Compose Buttons

We've now made the new Google Pay button available to Jetpack Compose developers with a new open source library compose-pay-button. Jetpack Compose is Android’s modern toolkit for building user interfaces when using the Kotlin language, and with this new library you can implement the Google Pay button in your Android apps with even less code than before.

Let's look at a quick example. Here you can see a typical Jetpack Compose UI, with the Google Pay button added. The button accepts a Jetpack Compose modifier for customization, and supports a variety of labels, in this case "Book with Google Pay".

setContent { Column() { PayButton( onClick = { println("Button clicked") }, allowedPaymentMethods = "<JSON serialized allowedPaymentMethods>", modifier = Modifier.width(300.dp), type = ButtonType.PAY_BOOK, ) } }


Google Wallet

Lastly, we've also released a corresponding library for Google Wallet, compose-wallet-button. The library provides a similar API to the Google Pay button, but instead bundles the same button assets available on the Google Wallet developer site, including both regular and condensed versions.

Image of the regular (left) and condensed (right) versions of the Google Wallet button
Figure 2: Both regular and condensed versions of the Google Wallet button are available in the new library.

Ready to get started? Check out the GitHub repositories for both compose-pay-button and compose-wallet-button where you can learn more about the libraries and how to add them to your Android apps!