Bringing our latest frontier model to Android Developers
Android Developers Blog
As agentic development accelerates, Android engineering is reaching an exciting new frontier: moving from assistive code completion to agents executing end-to-end under your direction. You have total choice and flexibility in the models and agents you use.
Gemini 4 Argon excels at deep work in complex, real-world tasks across domains including coding, finance, legal, cybersecurity, and science.
Starting today, Android developers can access Gemini 4 Argon across their development surfaces, including Google Antigravity (standalone and in Android Studio Canary) for Google AI Ultra subscribers, and in Android Studio and Google AI Studio via the paid tier of the Gemini API.Velocity & Autonomy: Closed-loop build self-correction
Argon has significant improvements in long-horizon autonomous execution and the ability to plan and run multi-step, complex software tasks over time.
- Self-Healing Build Loops: When a local build fails, the Antigravity execution harness captures error streams directly from Gradle daemons and Kotlin compiler logs. Using this feedback, Argon was able to iteratively diagnose build errors to arrive at a revised solution. To achieve this, the model maintained a consistent hypothesis across successive rounds of editing, enabling it to better address the true root-cause of build failures.
UI sophistication: Fluid motion & shader-backed Jetpack Compose
Argon demonstrates exceptional design craft, generating production-ready Jetpack Compose code out of the box:
- AGSL Shaders on the GPU: Argon applied advanced mathematical reasoning to write complex, production-ready Android Graphics Shading Language (AGSL) directly into Compose Modifier.graphicsLayer blocks and shader brushes. From live frosted glass shaders to dynamic lighting and ripple effects, Argon can handle complicated vector and rendering math that produces lightweight GPU shaders that run alongside fluid 120 FPS Compose animations.
A flexible developer experience with Android CLI
Antigravity operates across multiple surfaces, from the desktop app and IDE extensions to the command line. No matter which surface you prefer, the official Android CLI plugin is the de-facto engine that connects your agent to local Android tools, enabling it to run programmatic commands for common tasks and execute custom developer skills.
Starting today, you can access and configure this agentic workspace in two primary ways:
-
Setting up visually (Antigravity Desktop & Android Studio Canary)
- In the Antigravity Desktop App: Go to Settings > Customizations > Build With Google Plugins (or the Antigravity Plugin Marketplace), locate android-cli-plugin, and toggle it to Enabled
- In Android Studio Canary: Log in to your Antigravity account in the agent tool window to enable agentic workflows directly alongside your editor
-
Setting up via the Terminal CLI
For Google Antigravity, run:
agy plugin install android-cli-plugin -
For any terminal agent (via Android CLI), run:
android init
Availability & getting started
Starting today, Argon is rolling out globally to developers in supported regions. You can access and begin building with the model in your local environment across three primary development surfaces:
- Google Antigravity: Google AI Ultra subscribers can build with Gemini 4 Argon in the standalone Antigravity desktop app (available for macOS, Windows, and Linux) or directly via the terminal CLI
- Android Studio:
- Via Google Antigravity: Google AI Ultra subscribers can build with Gemini 4 Argon by logging into Antigravity within the latest Android Studio Canary.
- Via the Gemini API: Developers on the paid tier of the Gemini API can build with Gemini 4 Argon in Android Studio.
- Google AI Studio: Google AI Ultra subscribers or developers on the paid tier of the Gemini API can build with Gemini 4 Argon via Playground and Build in Google AI Studio.
- Firebase AI Logic: Starting today, developers globally on the paid tier of the Gemini API can use Gemini 4 Argon client-side to build intelligent features in their mobile and web apps via Firebase AI Logic.
- Choose your path: Confirm you have an active Google AI Ultra subscription to use Antigravity, or ensure you are on the paid tier of the Gemini API to use standard API surfaces (with introductory pricing available through November 30, 2026).
- Update your tools: Download the latest version of the Antigravity desktop app or CLI, and install the official Android CLI plugin (agy plugin install android-cli-plugin) to connect your agentic workspace directly to your Android Studio build tools.
We are eager to see the high-craft Android experiences you build at the frontier. Share your projects and feedback with us on X (@AndroidDev) and LinkedIn!
October 24th 2026, 12:49 pm
Introducing the Googlebook Linux Terminal Preview: A VM-Backed Environment for AI and Development
Android Developers Blog
Today, getting the most out of AI workflows requires access to a terminal with a command line, even if someone doesn’t identify as a programmer or software developer. With Googlebook, we’re excited to help users express themselves and gain access to these tools. Googlebooks come with pre-installed tooling to get you going. In this post, we’ll explore the capabilities of our new Linux terminal— now available in preview— share our future roadmap, and invite you to help us shape this ecosystem together.
Entry point for agentic development
AI agents use the terminal to install packages, write files, automate tasks, and create apps based on prompts written in plain language. For Googlebook to be the perfect companion for building and working at the frontier of agentic AI, the terminal needed to be easily accessible.We understand AI comes with risks. Googlebook OS has been architected with defense-in-depth as a core principle. All terminal commands run entirely inside the Linux VM, creating an isolated sandbox. This design allows users to grant `sudo` (administrator) privileges to AI tools like Antigravity and other agentic AI platforms, that make heavy use of command-line tools, while limiting opportunities for system corruption or unauthorized access to your private files. The VM boundary helps protect the host OS and unmounted files; each directory made available to the Linux VM is only mounted after the user’s explicit permission. Best of all, a one-click VM reset makes experimentation stress free because users can easily retain their files on the host file system when they reset the VM. You can even see your Linux files inside the Googlebook Files app, where a user can access local folders – including photos and files synced effortlessly from their Android phone. Using a quick Python script or AI agent, you can batch-process your files in seconds.
Linux VM benefits
The terminal provides users with the freedom to create and use the software that they choose. We’re excited to see users build tools that are hyper-specific to their needs as well as prototype apps for broader use. With a Debian Linux environment, users benefit from the mature ecosystem familiar to Linux developers. This means that they have access to the latest CLI tools and common developer workflows like `apt`, `git`, `ssh`, and common compilers and runtimes.Out of the box, our preview of the terminal on Googlebook has been optimized for rapid prototyping, web development, scripting, and agentic workflows via CLI. There is automatic localhost port forwarding to the host browser, and support for modern runtimes (e.g., Node.js, Python, Ruby, Go, Rust). Users can adjust the amount of memory made available to the VM to best suit their workloads. Our own engineers have been using Googlebooks to build a Linux kernel and use the terminal for platform engineering.
Looking ahead
We can’t wait for the terminal and Linux VM to continue getting more capable over time, including Linux GUI app support with integration directly into the app launcher. Here are some key areas on the roadmap:- We are working hard to get you building not only on Googlebook but also for your other devices. In addition to the existing network passthrough and wireless ADB, USB passthrough and support for ADB over USB are coming, enabling local device debugging and more from our Linux VM and Antigravity. Learn more about Antigravity on Googlebook.
- Our testers have been eager to run more complex tasks. To make this more seamless, we are adding dynamic memory and storage scaling for the VM.
- We will be adding GPU/NPU hardware acceleration for heavier local workloads, allowing users to leverage the performance and power efficiency of dedicated hardware.
- VM persistence and separation from the terminal window will better support long-running processes, when you want to take on more demanding agentic workloads.
We’re looking forward to seeing your creations and will be sharing more soon. Questions? You can reach us here for direct support. We've also really enjoyed hearing your early thoughts and feedback in r/googlebook.
October 24th 2026, 12:49 pm
New ways to drive smarter discovery, deeper engagement, and business growth on Google Play
Android Developers Blog
Today, we shared how we’re taking our “More than a store” vision into its next chapter. From You tab—now a personalized home base for your favorite apps and content—to Play Games Sidekick connecting over 2 billion players, Google Play is meeting users wherever they are. [1]
For developers, our goal is to help you connect with your audience and build a sustainable business. Below is a checklist to optimize your apps for our latest discovery features, new tools to deepen player engagement, and updates to our quality programs that reward great user experiences with lower service fees.
Reach the right users on Google Play and in the Gemini app
Earlier this year, we shared how new tools are transforming app and content discovery. Now, we’re expanding these features to make it easier for people to find your app.
- App comparisons on Ask Play: Ask Play already helps users find the right app through natural conversation, understanding context and adapting to follow-up questions. Now, it can generate dynamic, side-by-side app comparisons directly in search results. When a user compares details like subscription models or offline capabilities, Ask Play summarizes your store listing and user reviews to help them choose your app with confidence.
- Game finder: Tailored by each player’s gameplay habits, favorite mechanics, and community reviews, Game finder explains why a title is recommended and highlights what similar players and profiles you follow are enjoying. It begins rolling out to English-language users in the US today.
- Play in Gemini: People are increasingly discovering apps directly through conversations in Gemini—driving over 6 million app installs in just two months since launch. [2] When someone describes a specific need, such as organizing family recipes or finding a collaborative task manager, Gemini matches their request to your store listing and key features, so they can evaluate and install your app with a single tap. And now, with Gemini Live, they can get these same app recommendations through voice conversations.
To make sure your app is represented accurately everywhere users discover content—from Ask Play and Game finder to the Gemini app and Collections on home screens—review the following checklist:
- Keep store listings and promotional events fresh: Regularly update your descriptions, tags, and events in Play Console to highlight new features, seasons, and timely offers.
- Upload high-resolution media assets: Use clean images and video previews that look great across different screen sizes and devices.
- Validate deep links in Play Console: Use the new built-in deep link emulator to preview and test your links without needing a physical device.
- Integrate Engage SDK: Bring users back to your app by delivering personalized content across surfaces, including Apps Home, You tab, and Android tablets—now supporting 9 categories, including Education and Health & Fitness.
Deepen player engagement with social competitions and rewards
Once players find a game they love, recognizing their progress and connecting them with a community keeps them coming back. We’re introducing new ways for players to share their favorite moments, compete with friends, and earn rewards:
- Playbacks in Sidekick: With Sidekick—our in-game overlay now reached over 285M users—we bring Quests, Leagues, Sprints, and community features just a tap away.[3]
- Sprints: Building on Leagues, which turn in-game leaderboards into month-long competitive seasons, Sprints are fast-paced, 48-hour challenges that match 2 to 5 players of similar skills. It gives players an exciting reason to jump back into your game throughout the week.
- Quests: Beyond competing on leaderboards, players want their time and progress rewarded. We’re expanding Quests beyond Play Points to include in-game rewards like character skins, performance boosters, and valuable currencies.
You can turn on these competitive and social features by integrating Game Stats and Play Games Rewards:
- Game Stats: By sharing basic gameplay event signals—such as match completions, score thresholds, or key milestones—your games can show daily Streaks and become eligible for platform-wide competitions like Leagues and Sprints. Game Stats connects seamlessly with your backend data , giving you access to our engagement mechanics without rebuilding matchmaking or leaderboard systems.
- Play Games Rewards: Now generally available, you can set up ongoing in-game rewards that celebrate achievements and sync with Play Points. This helps you grow loyal players and keep them coming back.
Accelerate business growth with the Apps Experience and Level Up program
These new discovery and engagement tools help you deliver a better user experience while growing your business. For developers looking to go even further, our quality programs - Apps Experience and Level Up reward standout apps and games with lower service fees.
Titles integrating Level Up guidelines, like Summoners War, PUBG MOBILE, and Fruit Ninja are already seeing strong results by polishing graphics performance, integrating Game Stats, and launching Leagues and Quests. For example, PUBG MOBILE drove 22% uplift in new installs from high-value players, and achieved a 62% uplift in spend per buyer among engaged players.[4]
Both programs are now available in Australia, Japan, the EEA, UK, and US, and will roll out to Korea by the end of the year. We've also made it easier to submit and manage your program enrollment directly in Play Console.
Explore these new tools in Play Console today—where you’ll also start seeing a visual refresh rolling out this month to streamline your everyday workflow. Please keep sharing your feedback with us as we build the future of Google Play together.
October 24th 2026, 12:49 pm
Android Developers Blog is moving
Android Developers Blog
Posted by the Android Developers Team
Today, we are closing this chapter on Blogger and moving all official news and engineering insights directly to developer.android.com/blog. The new blog will have improved formatting, tighter integration with our technical content and be easier to navigate.
Update your bookmarks and RSS today.
Happy Coding!
October 24th 2026, 12:49 pm
How Instagram Direct engineers built AI-native UI architecture with Jetpack Compose and reduced toke
Android Developers Blog
Posted by Pavlo Stavytskyi, Software Engineer, Meta and Rebecca Franks, Developer Relations Engineer, Google
This blog post is written in collaboration with the Meta team.
Instagram Direct is one of the core surfaces on Instagram, handling billions of user messages every single day. Over years of iteration, the team squeezed every micro-optimization possible out of the legacy Android View system. However, maintaining and expanding a heavily optimized legacy surface creates significant technical debt and engineering overhead, especially as teams increasingly adopt declarative UI and AI coding assistants.
Adopting Jetpack Compose for Instagram Direct went beyond a typical UI modernization. The team built an AI-native UI codebase that is 50% smaller than the original implementation, while achieving a 35% reduction in AI agent execution time, 32% fewer engineer-agent exchanges, and a 33% reduction in token cost. In close partnership with Google, the team adopted Jetpack Compose while maintaining a high performance bar. Through the performance optimizations, Meta and Google improved Compose not only for Instagram, but for the broader Android developer ecosystem too.
Modernizing the codebase at massive scale
AI has rapidly become a daily companion for engineers in the industry, and applying it to a large-scale codebase like Instagram already yields real productivity gains. The Instagram Direct team set a more ambitious goal. Rather than simply pointing AI tools at the existing code, the team redesigned the codebase and its architecture to be AI-native by design, multiplying the impact of AI far beyond what retrofitting alone can deliver.
The Instagram Direct team chose Jetpack Compose as a key component for building an AI-native UI architecture. Its declarative nature ensures code is concise, predictable, and structurally easier for AI models to reason about, with fewer side effects, less implicit state, and clearer component boundaries.
The migration to Jetpack Compose required careful planning. Hundreds of millions of people send messages on Instagram every day, so the migration had to be gradual, smooth, with zero disruption to the experience while the team re-architected the foundation underneath it. To illustrate the scale of the challenge: Individual UI components can render in over 160 distinct state permutations, and a single conversation screen alone handles more than 200 distinct message types.
When migrating a codebase of this size to Compose, it's tempting to take the easy way out and embed Compose UI components inside the existing View hierarchy. As an incremental step during a gradual migration, that's perfectly valid. Over the long run, though, integrating Compose inside a View-based codebase poses a challenge. AI tools often take the path of least resistance. If you mix declarative and imperative UI code, AI is likely to blend them incorrectly, introducing subtle bugs, tech debt and performance regressions.
Building an AI-native UI architecture
At the scale of Instagram, a degree of architectural abstraction is unavoidable, and it is what keeps the app maintainable as it grows. Consider a common pattern, where every RecyclerViewitem type is modeled as a descendant of a custom RecyclerViewItem base class that exposes usual lifecycle hooks such as onBind.
Example 1
class ChatItem(
val features: FeatureFlagProvider
) : RecyclerViewItem<ComposeViewHolder, ChatUiState> {
// Imperative context:
// AI could often take the path of least resistance and generate a mutable
// state here, dispatched outside the ChatUiState. This class survives
// re-bindings and is shared across multiple items, ultimately leading to
// unexpected, hard-to-reproduce bugs.
var isPinned: Boolean = false
override fun onBind(holder: ComposeViewHolder, uiState: ChatUiState) {
// Imperative context
val isPinnedChatsEnabled = features.isEnabled("pinned_chats_feature")
// Declarative context
holder.composeView.setContent {
// Blending imperative and declarative contexts
if (isPinnedChatsEnabled) {
Button(onClick = { isPinned = !isPinned }) {
Text(if (isPinned) "Unpin" else "Pin")
}
}
...
}
}
}
In the snippet above, two problems creep in. First, the isPinnedChatsEnabled flag is read in imperative code and then captured inside a Compose lambda, a subtle coupling across paradigms. Second, isPinned lives as a mutable field on the item itself rather than in ChatUiState, so it survives RecyclerView re-binding and recycling across rows, leaking and producing bugs that are painful to reproduce.
Even when the code is cleaned up by giving the item a dedicated @Composable function, the same problems remain.
Example 2
class ChatItem(
val features: FeatureFlagProvider
) : ComposeRecyclerViewItem<ChatUiState> {
// Imperative context
val isPinnedChatsEnabled = features.isEnabled("pinned_chats_feature")
var isPinned: Boolean = false
// Declarative context
@Composable
override fun Content(uiState: ChatUiState) {
// Blending imperative and declarative contexts
if (isPinnedChatsEnabled) {
Button(onClick = { isPinned = !isPinned }) {
Text(if (isPinned) "Unpin" else "Pin")
}
}
...
}
}
This is deliberately a simple example, but it illustrates a broader issue— the fewer boundaries AI is given, the lower the quality of the code it produces over time. Guardrails and skills help, but they are not enough on their own, because when AI hits friction it will often route around them to unblock itself.
To make the codebase AI-friendly, it needs to follow two practical rules:
- Minimize dependency on custom context. The more bespoke, codebase-specific knowledge an AI agent needs to make a correct change, the lower the quality of its output. The closer the codebase is to known best practices, the better the AI results.
- An AI-first codebase must enforce its own boundaries. Patching design gaps with AI skills doesn't scale, since every skill loaded into context costs tokens and can degrade the agent's performance. Instead, the architecture itself should carry that weight. AI agents naturally take the path of least resistance, so the design should make that path lead to correct, high-quality code, while making poor design decisions hard and expensive to express.
A list item can still be represented by its own abstraction, but in this case all the Compose code lives in the constructor, so it has no access to class members or state, and its only source of arguments is the constructor. This makes it equivalent to a plain @Composable function, while conforming to the existing architecture.
Example 3
class ChatItem(
val features: FeatureFlagProvider,
val onPin: (Boolean) -> Unit,
) : ComposeItem<ChatUiState>(
// Compose UI
content = { uiState: ChatUiState ->
val isPinnedChatsEnabled = features.isEnabled("pinned_chats_feature")
if (isPinnedChatsEnabled) {
Button(onClick = { onPin(!uiState.isPinned) }) {
Text(if (uiState.isPinned) "Unpin" else "Pin")
}
}
...
},
)
Migrating a codebase of this size is a massive undertaking. For a long time, the hundreds of UI components that make up the majority of Direct UI had to coexist with their legacy counterparts, with both maintained in parallel. AI workflows helped make this parallel migration possible by speeding up the process of writing massive amounts of code. That approach is what let the Direct team perform the migration in record time, all without disrupting the rest of the team, who kept shipping the features that improve the experience of millions of people every day.
Multiple engineers ran their own AI agents against a shared knowledge base of reusable skills and conventions built during the migration. That kept workflows and best practices in sync across the team, rather than having each engineer rediscover them. Within each surface, the team performed the migration in the following stages:
- Write all the Compose code with AI.
- Polish it, handling edge cases and closing performance gaps, until the UI was rolled out to real users in a public test.
Splitting the work into two stages per screen lets one engineer move quickly through the entire surface, settling the architecture and the tricky edge cases up front. With that groundwork in place, others can focus on getting the UI production-ready without stopping to make those technical decisions themselves, keeping the overall migration fast.
The results of the migration validated the approach. For migrated Instagram Direct surfaces, Jetpack Compose allowed the team to reduce the total amount of UI code by 50%. Less code for AI to generate is associated with higher-quality output and lower token cost per task.
An internal data analysis of the Android codebase for Instagram Direct compared AI agent sessions working on Compose UI against the same tasks using Android Views. The efficiency gains were clear across two dimensions:
- Per character of landed code: Compose required 32% fewer engineer-agent exchanges and 35% less agent execution time (the elapsed time from when an agent starts working on an engineer’s request until it returns a response).
- Per agent session: The overall token cost dropped by 33% with Compose in comparison to Views.
We report both output efficiency and typical session numbers because they are independently useful outcomes. The engineer-agent exchanges and execution time figures compare resource use per unit of landed output, while the token figure compares total cost for a typical agent session.
The data also revealed a consistent difference in how the two frameworks handle complex or fragile code. Meta tracks this using a risk score of code changes, which evaluates overall code quality and the likelihood of a change causing production incidents. The analysis measured an agent’s resource efficiency using a composite of token consumption, agent’s execution time and the engineer to agent interactions. As files accumulate a higher risk score, AI agent sessions naturally become less resource efficient.
When a file’s accumulated risk score doubles, the UI implemented with Android Views reduces agent resource efficiency by 30% (per landed character). In the same circumstances, the reduction by Jetpack Compose UI is only 9%.
Through partnership between Google and Meta, the Instagram Direct team brought a fresh perspective to Compose adoption — approaching it through the lens of the codebase's AI-readiness, not just a UI rewrite. This work revealed Compose's strength in serving as a foundation for building AI-first codebases and architectures, especially when applied at the scale of apps like Instagram.
Performance optimizations
Instagram Direct is one of the most integral surfaces of the app, and people expect it to feel fast and responsive at all times. Adopting Jetpack Compose effectively meant a substantial UI rewrite, and the number-one goal was to preserve the high-quality experience with no regressions.
Years of iteration had already pushed the legacy View-based implementation on Instagram to an exceptionally high performance bar, and the team needed to meet that same standard while moving to an entirely new UI framework.
Instagram measures hundreds, if not thousands, of performance metrics. For Compose adoption, the following three were the most important:
- Time to interact - the amount of time between opening the screen to being able to use it.
- Time to fully load - the amount of time between opening the screen to when all the content is fully loaded (i.e. images).
- Scroll performance - how smoothly the screen scrolls, without dropped frames.
These metrics are tracked at runtime in production, making it possible to run A/B tests comparing the migrated Compose UI against the legacy UI and evaluate the performance impact of this effort.
A common way to approach a migration like this is to start small, moving over a handful of UI components, gathering data, and studying how they behave. While helpful, these early results only paint a partial picture, providing false negatives against Compose adoption because:
- Not representative — one migrated UI component can provide useful data about its overall performance on a particular screen. However, different components behave differently for reasons that don't generalize, so you can't always extrapolate from it.
- Interop cost — a small Compose piece inside a big View codebase pays an unpredictable bridging cost between the two systems. That overhead distorts the measurement, so early small-scale results don't reflect what full migration would actually look like.
The result is that small migrations, while useful, don't always reflect the full impact of Compose. The more of a surface is migrated end-to-end without bridging interruptions, the clearer and better the picture becomes performance-wise.
The core screens in Instagram Direct are built around long lists of varied item types, originally implemented with RecyclerView. The architecture relies on custom abstractions for scalability, but it remains bound to the lifecycle of the View-based system.
The team's primary undertaking was a gradual migration of several hundred individual list items to Compose within the existing RecyclerView-based architecture, rolling them out in production in small independent groups under A/B tests — all of it without visible changes to the user's messaging experience.
The biggest downside of such a setup is a significant dependency on the legacy View system through a core RecyclerView architecture, even after the full migration of every list item to Compose. As a natural next step, the team decided to invest in replacing the RecyclerView-based core architecture with the Compose-native alternative — LazyColumn.
This means Compose UI components should be abstracted away from the framework they are enclosed in while still being compatible with both RecyclerView and LazyColumn at the same time. Equally important is the ability to switch between the two at runtime via feature flags, to enable A/B testing.
While the new Compose items are natively compatible with LazyColumn and can be plugged into an uninterrupted composition tree, an interop API was created to slot them into a RecyclerView as well. This made it possible to roll out the LazyColumn setup under an A/B test side-by-side with RecyclerView — reusing the same Compose items and polishing performance, without disrupting the rest of the team building and refining features.
The scale, complexity and sensitivity of Instagram to even the smallest regressions posed a unique challenge for Jetpack Compose. Addressing these required an iterative, hands-on partnership. Working closely together, Google and Meta engineers analysed metrics to pinpoint and design new Compose capabilities to meet or exceed the View-based benchmarks. As a result of this partnership, the following additions to Jetpack Compose stand out: Pausable composition with LazyLayoutCacheWindows and visibility tracking.
Pausable composition with LazyLayoutCacheWindows
Pausable composition (enabled by default in Compose 1.10) allows expensive lazy-list items to be composed incrementally across frames to prevent jank. When paired with LazyLayoutCacheWindow (added in Compose 1.9), the combination significantly improves scroll smoothness. In recent internal testing at Meta, combining Pausable composition with a one-viewport LazyLayoutCacheWindow reduced large frame drops per minute (LFDs/m) by about 13% compared with vanilla Compose. Cache Window on its own reduced it by about 8% against the same baseline. LFDs/m is an internal metric Meta uses to track noticeable stutters while scrolling.
Using a LazyLayoutCacheWindow in your app prepares and retains off-screen items within a pixel-based band around the viewport to enable fast flings. To take advantage of LazyLayoutCacheWindows in your app, you can use the latest Compose 1.13.0-alpha03 and set it up as shown in the example below:
val cacheWindow = LazyLayoutCacheWindow(ahead = 150.dp, behind = 100.dp)
// OR
val cacheWindow = LazyLayoutCacheWindow(aheadFraction = 0.5f, behindFraction = 0.3f)
LazyColumn(state = state, cacheWindow = cacheWindow) {
...
}
There are two ways to configure the cache window. Both describe the same thing: how much off-screen content to keep composed, but in different units.
- Dp: fixed absolute length.
ahead = 150.dpkeeps 150dp of content composed past the visible edge regardless of device. - Float: fraction of the viewport.
aheadFraction = 0.5fkeeps half a screen composed ahead, so the absolute amount scales with screen height supporting various form factors: more on a tablet or unfolded foldable, less on a compact phone.
The Instagram team fine-tuned the cache window's float fractions specifically for Direct's content structure and item sizes. Since the ideal values vary depending on the specific UI parameters, finding the right balance requires some experimentation.
Impression logging with onVisibilityChanged
The onVisibilityChanged (added in Compose 1.9.0) API was another key result of the technical partnership between Google and Meta. It gives large-scale Jetpack Compose surfaces a consistent way to know when a composable is actually visible on screen, replacing custom, hand-rolled implementations used in the past. Within Instagram Direct alone, these visibility signals are used across hundreds of files to support product quality metrics that depend on whether UI elements were actually shown to people.
Startup performance
The adoption of Jetpack Compose for Instagram Direct led to unexpected performance improvements across other surfaces of the app. The Jetpack Compose runtime carries a warmup cost you pay only once, and because messaging is a high-traffic surface often visited early in a user session, other surfaces across Instagram that rely on Compose saw noticeable performance improvements.
The startup performance of Compose UI inside Instagram Direct itself was optimized through using Baseline Profiles, which pre-compile hot code paths at install time so Compose renders quickly from the very first launch.
Lessons from the Instagram Direct migration to Jetpack Compose
- Jetpack Compose has an immediate return on investment: You do not need to be using advanced AI workflows to benefit from Compose. With the ~50% reduction in code, it means less code to maintain, and reduced surface area for bugs.
- Designing an AI-native architecture led to significant wins, including a 35% reduction in AI agent execution time, 32% fewer engineer-agent exchanges, and a 33% reduction in token cost.
- Although there are plenty of interop APIs and support for combining Views and Compose together, aim to migrate bigger surfaces over individual small components. This keeps the UI within a single, uninterrupted composition hierarchy and unlocks all the best Compose-native performance optimizations.
- Pair Pausable composition with LazyLayoutCacheWindow: Pairing these two together yields better results than cache windows alone. With only the cache window, a heavy item could still try to compose in a single pass, potentially overrunning the frame budget.
- Contribute to Compose itself! Meta has partnered with the Jetpack Compose team to bring their feedback and ideas to life within Compose. Working on an open-source toolkit means we all benefit when bugs and performance improvements are made centrally. So, make your feedback known!
Adopting Jetpack Compose unlocked significant gains in AI-assisted development while simplifying day-to-day UI engineering at Instagram. The declarative approach reduces boilerplate, makes state easier to reason about, and improves overall developer productivity. The Instagram engineering team is looking forward to bringing Compose to more surfaces across the app, and the continued collaboration between Google and Meta to bring more improvements to Instagram and Jetpack Compose users alike.
If you haven’t yet tried out Compose, now with AI-assistance, migrating to Jetpack Compose is easier than ever.
Acknowledgements. Thank you to Michal Zielinski and Matthew Du from Meta, and Andrei Shikov and George Mount from Google, for their work bringing performance improvements to Compose through the collaboration between Meta and Google! Thank you also to Gary Ye from Meta for helping bring Compose to Instagram Direct, and to Gopal Juneja from Meta for supporting this effort through data science!
October 12th 2026, 3:05 am
Android Bench 2.0: Pushing the frontier with challenging long-horizon tasks
Android Developers Blog
When we first launched Android Bench, we built a rigorous foundation for evaluating how large language models (LLMs) assist developers with real-world Android tasks. As AI models and agents rapidly evolve, we’ve been updating our methodology, such as aligning our benchmark framework with the Harbor framework. Today we’re releasing the first set of long-horizon tasks (LHT), which are tasks of great complexity that take an engineer multiple days or even a week to complete. We are also introducing agentic evaluation, starting with agents from corresponding model providers. This addition brings us to Android Bench 2.0—a major upgrade designed to evaluate AI models and agents against the scale, ambiguity, and complex multi-step problem solving that you tackle every day.
From incremental fixes to long-horizon tasks
The first iteration of Android Bench, along with similar early AI coding benchmarks, focused on incremental changes to existing repositories, in many cases limited to bug fixes or smaller feature requests. This was a reflection of the capabilities of AI assistance at the time, as well as how you were using it.
To continue helping you find the models and coding agents best suited to your development workflow, we have raised the bar of our evaluations to match the work you delegate to AI. Android Bench 2.0 mirrors these ambitious challenges with LHTs that include upgrading dependencies, adding new features, building apps from scratch, or converting a cross-platform app to Android.
Complex tasks require a more nuanced evaluation and scoring
On multi-day engineering tasks, binary pass or fail grading doesn’t capture the full picture.
For example, an agent might refactor 40 screens to Jetpack Compose, set up database tables, and pass 90% of requirements, but fail a single edge-case assertion. Binary scoring rates this run as 0%, obscuring the model's architectural capabilities. We are moving to continuous scoring to provide a more meaningful signal, both for model development and for your understanding of how AI can help you.
We calculate this completion rate through a combination of factors like functionality, visual fidelity, and avoiding regressions. We also apply objective scoring penalties for deviations from evaluation instructions or structural constraints. Check out the updated leaderboard and click into each model’s card view to see additional elements such as the pass rate, completion rate, and average costs per model and per task.
The highest pass rate for LHTs is around 28%, much lower than the ~91% for the original tasks in the benchmark.
Long-horizon tasks uncover helpful insights for AI assistance
Beyond measuring how well AI handles long-running tasks, the LHT dataset helps us learn more about the strengths and weaknesses of tested models, and we offer you more practical guidance.
Across model tiers, AI does a better job at writing new code rather than refactoring existing code. Refactors and migrations get trickier because success depends on architectural complexity rather than code volume.
Models show strong capabilities on well-established, deterministic transformations, such as converting Java to Kotlin, swapping Retrofit for Ktor, or introducing a ViewModel layer. They apply these patterns consistently, even across 125+ files and 8,000+ lines of code.
However, models struggle when tasks require runtime validation (like missing dependency injection graphs), involve breaking framework changes, or run into knowledge gaps with unreleased libraries. Porting cross-platform apps to Android remains an open challenge—no model hits a 100% pass rate, and frontier models reach at most a 80% completion rate.
Introducing agent evaluations
To help you get a better sense of how models perform when integrated into your agentic workflows, we are adding commonly used agents into our evaluation. We're starting by running new models against LHTs with agents from the corresponding model provider. For example, we ran GPT 5.6 Sol on Codex, and Gemini 3.8 Flash on Google Antigravity. This pairing shows how harness design positively impacts developer outcomes, as we’ve seen prompt caching and compact tool windowing can result in token reductions.
We’ll be expanding this in the future by also highlighting results across various model and agent combinations, to help you discover which combinations work best for you and your team.
We invest in this measurement because it’s important for you to be able to use your agent and model of choice for Android development, and we'll have more to share with you in the coming weeks.New models added
In addition, we are continuing to expand our leaderboard to ensure you have the most up-to-date data for your development decisions. We added Gemini 3.8 Flash, Gemini 3.7 Flash, OpenAI’s GPT-6, Anthropic’s Fable 5.1, Kimi K3, and Qwen 3.8 Max, with OpenAI’s GPT-6 Astra at the top with a 28% pass rate.
Looking ahead
Android Bench 2.0 delivers a robust environment for measuring AI for Android development. By combining long-horizon tasks, multimodal evaluation, agents, and continuous scoring, we hope to empower AI research teams to build more capable, dependable AI coding partners, and we hope to provide you with more transparency about your options for AI development.
Check out the updated leaderboard along with the updated methodology. Your feedback directly influences how we evolve Android Bench, so please continue to share your feedback with us on GitHub, as well as our social channels like X and LinkedIn.
October 12th 2026, 3:05 am
Bring your Android game to the car screen today
Android Developers Blog
Posted by Jan Kleinert, Developer Relations Engineer, Android for Cars
Today, the games category for Android Auto and cars powered by Android Automotive OS with Google built-in is officially graduating from beta to general availability. Our early access partners have already been bringing games to the parked-only experience for cars, and you can browse these in our latest collections of games for Android Auto and games for Android Automotive OS.
Bringing your game to cars lets you reach users in their vehicles during natural downtime, such as while waiting at a charging station or for a curbside order pickup. Today's milestone means that we're opening up access so developers can now publish games to the open testing and production tracks on Google Play. In this post, we'll cover how to adapt your existing Android game for the car screen, focusing on key technical requirements and publishing criteria.
Implement car support for your game
If you're already following best practices for building adaptive apps, bringing an existing Android game to cars primarily involves configuring your app manifest and ensuring your game respects the vehicle parked state.
Mark your app as a game
To distribute your app in the games category, you need to explicitly declare its category. Add the android:appCategory="game" attribute to the <application> element of your manifest file:
<application ...
android:appCategory="game">
...
</application>
Declare support for Android Auto
Games are supported on Android Auto on devices running Android 15 and higher. To declare that your game supports Android Auto, include this <category> element in the intent filter of an activity in your manifest file:
<activity ...
<intent-filter>
<action android:name="android.intent.action.MAIN" />
...
<category android:name="android.intent.category.CAR_LAUNCHER" />
</intent-filter>
</activity>
Generally, the android.intent.category.CAR_LAUNCHER category element is placed in the same intent filter as the android.intent.category.LAUNCHER element, but it can be in another activity's intent filter if you prefer to launch a different activity.
Declare support for Android Automotive OS
To declare that your game supports Android Automotive OS, include the android.hardware.type.automotive <uses-feature> element in your manifest file.
<manifest ...
...
<uses-feature android:name="android.hardware.type.automotive"
android:required="false" />
...
</manifest>
The android:required value has different restrictions depending upon which track you choose to distribute your Android Automotive OS app. If you distribute your Android Automotive OS app on the mobile track, android:required must be set to "false". However, if you distribute on the Android Automotive OS dedicated track, you can set android:required to "true", "false", or leave it unset. Leaving the value unset has the same effect as setting android:required to "true", and means that your app is available only for distribution on Android Automotive OS devices.
Handle the parked state
Cars introduce a unique physical context with a driving state and a parked state. Certain types of apps, like games, are considered parked apps and aren't permitted to run while the vehicle is in motion to avoid driver distraction. By default, Android Auto and Android Automotive OS block activities from being used or launched when the vehicle is in motion or when user experience (UX) restrictions are active. To make sure your game complies with driver distraction guidelines, don't include the distractionOptimized metadata element in any activity in your manifest. You must also ensure that your game audio stops when the user starts driving and can't be unpaused while the vehicle is in motion.
Additionally, when the user relaunches the app from the home screen, your game must restore the app state as closely as possible to the previous state. Test your game for responsiveness and ensure it doesn't freeze or stutter during gameplay.
Declare game controller support
Car screens support touch input, but many users prefer playing with a connected gamepad. If your game supports controller input, declare the android.hardware.gamepad feature in your manifest to help boost the visibility of your app in the Google Play Store to users specifically seeking controller-compatible experiences.
<uses-feature android:name="android.hardware.gamepad" android:required="false"/>
Set the android:required attribute to false to indicate your app supports controllers, but the use of controllers is optional. Don't set the android:required attribute to true unless a controller is mandatory for your game.
Support common screen sizes and aspect ratios
Car displays come in various shapes and aspect ratios, including portrait and wide landscape screens. For a great user experience, make your game fully adaptive to different screen sizes so that it runs full screen without letterboxing or pillarboxing. For Android Auto, refer to the guidance for testing against canonical screen sizes and use bundled hardware profiles when testing with the emulator for Android Automotive OS.
Publish your game to cars
After you've implemented the necessary changes, you can opt in to Android Auto and Android Automotive OS form factors in the Google Play Console. Before submitting to production, test your game against the car app quality guidelines for games.
Use the Desktop Head Unit to test your app's Android Auto compatibility, and use the Android Automotive OS emulator to test the experience on Android Automotive OS. Your game will be reviewed against the car app quality guidelines for the games category before it is approved for open testing or production.
Get your games on the road
With the games category now generally available, it is the perfect time to optimize your titles for cars. To learn more about implementation details, review the documentation at Build games for cars.
October 12th 2026, 3:05 am
Driving growth on Google Play: The next era of subscriptions
Android Developers Blog
The subscription landscape is evolving rapidly, especially with the surge of generative AI and increasingly sophisticated app experiences. As the ecosystem shifts, we recognize that developers need more flexible and robust tools to monetize effectively while improving the LTV of recurring purchases. On Google Play, we are continuously expanding our subscription platform to help you drive growth, adapt to new business models, and meet your users exactly where they are.
Here is a look at the capabilities we are testing and rolling out to support the next generation of subscriptions, along with powerful existing features designed to maximize your conversion and retention.
Unlock new ways to sell and grow with flexible monetization models
As we look at the next few years of the subscription business, flexibility is paramount. Developers building GenAI tools, entertainment, educational platforms, and business solutions need adaptable pricing and packaging models to scale access beyond the individual user and capture higher cart value at checkout.
Multi-Quantity Subscriptions: Scale subscriptions to teams
To support collaborative and team-wide or group usage, Play is introducing Multi-Quantity Subscription Purchase. This allows users to make multiple subscription purchases in a single transaction and easily assign those as seats or subscriptions to team members or students. This is a game-changer for productivity, EdTech, and GenAI developers looking to sell team-wide subscription access seamlessly.
Usage-Based Billing: Support AI and variable-cost features
For apps with variable computing costs—like AI generation tools or other usage-based services—rigid recurring subscriptions do not always fit. Usage-Based Billing enables you to set up prepaid metered billing where users can automatically top up their balance whenever it falls below a set threshold. This ensures uninterrupted service for your users while protecting your margins.
Beyond these flexible models, we are also making it easier to package your products and upsell creatively at checkout:
Mixed Carts: Sell subscriptions and one-time products in a single checkout
Historically, subscriptions and one-time products were purchased in separate transactions. If a user wanted to buy a monthly membership alongside a starter pack of in-app currency or bonus credits, they had to complete two separate checkout flows.
Mixed Carts bridges this gap for developers who want to sell both auto-renewing subscriptions and one-time products (OTPs). By enabling you to process an auto-renewing base subscription alongside OTPs in a single API call and unified checkout sheet, Mixed Carts streamlines the transaction process.
This unified experience also opens up powerful upsell opportunities for your business—such as offering targeted discounts if an end user purchases a complete bundle of a subscription and complementary in-app items together.
Cross-Developer Bundling: Partner across apps to unlock shared growth
Partnerships are a proven strategy for acquiring new users and driving growth. With Cross-Developer Bundling, you can create and sell a hard bundle of two or more complementary subscriptions in your own catalog.
This capability allows you to team up with other developers—or combine offerings across your own portfolio of apps—to deliver massive value through a single purchase. For example, if you manage a language learning app, you can now create a single SKU that bundles your monthly membership with a partner's premium travel guide subscription, offering users a combined subscription at a discounted rate.
By sharing the acquisition benefits, you can seamlessly reach new audiences and secure more recurring revenue for your business.
Maximize subscription performance: Keep and win back the users you’ve earned
Acquiring a subscriber is only the first step—long-term growth depends on minimizing friction across the billing lifecycle. We are heavily invested in improving subscription performance to help you prevent involuntary payment declines and retain your subscribers.
The In-App Messaging API: Resolve payment declines and price change updates in-context
Available now to all developers, we highly encourage adopting the In-App Messaging API. This tool allows you to meet end users exactly where they are—inside your app—with critical transactional messages. You can use this API to:
- Prompt users to fix a payment decline immediately.
- Notify users of upcoming price changes transparently.
By handling these critical account states gracefully within the app experience, you can continue running your business without disrupting the user journey. Learn more.
Dynamic Grace Period: Tailor payment recovery windows with predictive models
Involuntary churn from payment declines is often addressed with a static, one-size-fits-all grace period. However, fixed durations force a difficult trade-off between giving users enough time to resolve payment issues and managing developer service costs during unpaid periods. With Dynamic Grace Period, Google Play utilizes machine learning and heuristic models to tailor the grace period duration for individual subscribers following a payment decline. By intelligently matching the recovery window to the user's recovery likelihood, this capability is designed to help developers better balance renewal recovery against unpaid service access. To ensure consistency with your business rules, Google Play automatically adjusts the subsequent account hold duration, preserving your total configured recovery window without requiring client-side code changes.Retention Offers and Plan Change: Prevent voluntary churn in the cancellation flow
Acquiring new subscribers is expensive, making it critical to engage and retain your existing user base. When users consider canceling, capturing their attention before they leave is essential for protecting your customer lifetime value. With Retention Offers, you can present developer-funded incentives—like a discount—directly within the Play Store cancellation flow.
For users who may not be eligible for a discount or promotional offer, you can suggest a Plan Change to a lower-priced tier, ensuring you offer a flexible path to keep them engaged in your app rather than losing them entirely.
Native Winback Offers: Re-engage lapsed subscribers directly on the Play Store
A canceled subscription doesn’t have to be the end of the user lifecycle. Former subscribers already understand the value of your app—they often just need the right incentive at the perfect moment to return. Traditional winback campaigns rely on email or push notifications, which fall flat if a user has uninstalled your app. Google Play's Subscription Winback Offers close this gap in your re-acquisition strategy by reaching users directly on the Google Play Store, helping you present lapsed users with personalized offers that make coming back easier than ever.
Behind the scenes: The revenue shield you don’t have to build
Alongside the tools you configure in Play Console, Google Play runs a continuous engine of zero-lift optimizations behind the scenes to grow your subscriber base and reduce involuntary churn—without requiring a single line of developer code. From smart payment retries and automatically cycling through backup payment methods for opted-in users, to sending intelligent, context-aware reminders during grace periods and account hold, Play works continuously to recover failed transactions seamlessly.
We also protect your revenue with built-in fraud and abuse prevention systems that block bad actors from exploiting promotional offers or manipulating billing cycles. This ensures your promotional budgets reward legitimate, high-value subscribers—securing your business while naturally lifting overall retention.
Many of these features are currently available or rolling out through our Early Access Program, meaning capabilities are in active testing with select partners to gather feedback before rolling out more broadly in Play Console. If you work with a Google Play partner manager, you can reach out to express interest as programs open. To learn more about our current subscription capabilities and get your app ready for what’s next, explore our Google Play Billing subscriptions documentation.
October 12th 2026, 3:05 am
Build intelligent Android apps: In-app agentic workflows
Android Developers Blog
Posted by Jolanda Verhoef, Senior Developer Relations Engineer, Android Developer Relations
Welcome back to the blog post series "Build intelligent Android apps" where you take a basic Android app and transform it into a personalized, intelligent, and agentic experience. In our previous post you learned how to connect to the intelligence system using AppFunctions.
In this post, you will learn how to build autonomous in-app agentic workflows running in the cloud.
Sometimes a task is too complex for a single device session. For example, booking a complete holiday itinerary involves coordinating flight times, selecting hotel rooms, reserving museum tickets, and planning restaurant reservations. If you run this multi-step process directly on a mobile device, the app might get closed and lose your progress. Managing all these steps and API credentials on a phone also gets complicated quickly.
For these long-running, multi-step workflows, you can use a custom self-hosted backend. The backend executes the booking agents in the background, while the Android app connects to the session, visualizes the progress, and requests user input only when necessary.
Using a cloud-hosted agentic backend offers a few advantages:
- Background execution: Booking agents run autonomously in the cloud, so progress is never lost if the mobile app goes to the background or loses internet connectivity.
- Complex multi-agent orchestration: A coordinator agent can delegate bookings to specialized subagents and handle dependencies between them.
- Client-agnostic UI rendering: The backend describes the interface structure dynamically, letting you update the UI layout without releasing a new client version.
With these benefits in mind, we added a Booking Assistant to Jetpacker that coordinates flights, hotels, museums, and restaurant reservations. Let's look at how we orchestrated a multi-agent system powered by the Agent Development Kit (ADK), with the Agent-User Interaction protocol(AG-UI) and Agent-to-User Interface protocol (A2UI) to send and display interactive cards natively in Jetpack Compose.
Powering complex workflows with ADK agents
Rather than coordinating the orchestration flow manually using custom REST endpoints or complex web sockets, you can use the Agent Development Kit (ADK). With ADK, you can define agents and equip them with python function tools to query databases and execute bookings.Here is how to define a simple agent and run it using ADK:
# android/booking-server/booking_server.py
# Note: ADK supports many different coding languages. For now, use the Python version as it includes support for A2UI which we'll use later in this blog post.
from google.adk import Agent
from google.adk.runners import InMemoryRunner
from google.adk.tools import FunctionTool
# Define custom tools to interact with database
def search_flights(destination: str, date: str) -> list[str]:
# In production, here you would query our flight database and return dynamic results
return ["10:00 AM", "2:00 PM"]
def reserve_flight(flight_time: str) -> str:
# In production, here you would save the reservation transaction
return "Reserved flight at " + flight_time
# Instantiate the booking agent with specialized tools
flight_agent = Agent(
name="Flight Booker",
model="gemini-3.1-flash-lite",
instruction="Help the user search for flights and book a reservation.",
tools=[
FunctionTool(search_flights),
FunctionTool(reserve_flight, require_confirmation=True)
]
)
# Run the agent in memory using a session ID
runner = InMemoryRunner(flight_agent)
async for event in runner.run_async(user_id=user_id, session_id=session_id):
if event.content:
print("Agent said:", event.content)
When you run an agent using this setup, ADK manages the execution steps for you. It automatically tracks the conversation context, routes messages between the user and the model, and executes the registered tools when the model requests them. This allows you to focus on writing clean procedural logic while the framework handles the orchestration in the background.
To connect this backend agent to our Jetpacker app, the server needs a way to stream updates in real time to the device, which is handled using the AG-UI protocol. The agent also needs a structured way to describe and update interactive components (like option selectors and seating grids) dynamically on the phone, which is where the A2UI protocol comes in.
Standardizing agent-client communication with AG-UI
Running agents in the cloud and rendering UI on Android requires a standard communication channel. For this, you will use the AG-UI protocol.AG-UI is a bidirectional transport layer protocol that standardizes message types between agents and UI clients. The agent can inform the client of lifecycle events, text messages, tool calls, and state management. The client, in turn, can send user text messages, tool call results, and custom action events back to the agent.
On the server side, it yields updates formatted as standard Server-Sent Events (like event: TEXT_MESSAGE_CONTENT containing the JSON delta). On Android, the Kotlin SDK listens to this stream and automatically maps the payloads to type-safe client events:
// https://github.com/android/ai-samples/tree/main/jetpacker/android/feature/trip/booking_assistant/src/main/kotlin/com/example/jetpacker/feature/booking_assistant/BookingAssistantViewModel.kt
import com.agui.client.agent.HttpAgent
import com.agui.client.agent.HttpAgentConfig
import com.agui.core.types.RunAgentInput
import com.agui.core.types.UserMessage
import com.agui.core.types.TextMessageStartEvent
import com.agui.core.types.TextMessageContentEvent
import com.agui.core.types.TextMessageEndEvent
val config = HttpAgentConfig(
agentId = "booking-assistant",
threadId = threadId,
url = "https://<your-backend-url>"
)
val agent = HttpAgent(config, httpClient)
// Set up the input with the session thread and user instruction
val input = RunAgentInput(
threadId = threadId,
runId = runId,
messages = listOf(UserMessage("Book a flight to Paris"))
)
// Run the agent flow and collect lifecycle events
agent.runAgentObservable(input)
.collect { event ->
when (event) {
is TextMessageStartEvent -> { /* ... */ }
is TextMessageContentEvent -> { /* ... */ }
is TextMessageEndEvent -> {
// Handle the completed message
}
}
}
You can then write a UI to render these different types of standardized AG-UI events. This will give you the prototypical "Chatbot" experience:
Letting the agent speak UI with A2UI
Traditional chatbots typically return plain text or custom JSON payloads. When building complex interfaces, the client application has to parse these payloads and map them to specific, pre-built screens. This creates a dependency: every time you add a new feature, change the layout, or support a new user interaction, you have to update both the backend agent and the mobile application. This requires publishing an app update and waiting for users to install it.To solve this, use the A2UI protocol. A2UI allows agents to describe the UI components to render on the client dynamically. The client app declares a catalog of components it supports, and the server sends a JSON payload specifying the component layout and properties:
{
"version": "v0.9",
"updateComponents": {
"surfaceId": "Flight Reservation",
"components": [
{
"id": "flight_option_picker",
"component": "InteractiveOptionPicker",
"properties": {
"prompt": "Select a flight time:",
"options": [
"10:00 AM",
"2:00 PM"
],
"selectedIdx": null,
"confirmBtnText": "Confirm Flight"
}
}
]
}
}
The server specifies which catalog components to render along with their active property values, cleanly decoupling the client's visual implementation details from the agent's workflow state.
Designing the backend UI schema
For the agent to generate these JSON payloads correctly, it needs to know which components are available and what properties they accept.To do this, use the ADK A2UI integration. Instead of manually writing prompt instructions for every component in our catalog, the A2uiSchemaManager compiles their JSON schemas and layout instructions directly into the system prompt. This ensures the model learns the exact structure and formatting rules it must follow to generate valid A2UI payloads:
# android/booking-server/booking_server.py
from a2ui.schema.manager import A2uiSchemaManager
from a2ui.schema.constants import VERSION_0_9
from a2ui.schema.catalog import CatalogConfig
from a2ui.basic_catalog.provider import BasicCatalog
# Initialize A2UI Schema Manager with custom booking component catalog
schema_manager = A2uiSchemaManager(
version=VERSION_0_9,
catalogs=[
BasicCatalog.get_config(version=VERSION_0_9),
CatalogConfig.from_path(
name="https://example.com/catalogs/booking_assistant/v1/catalog.json",
catalog_path="booking_catalog.json"
)
]
)
# Compile prompt instructions including the A2UI JSON schema
A2UI_SYSTEM_INSTRUCTION = schema_manager.generate_system_prompt(
role_description="You are a helpful travel booking assistant.",
ui_description="Use InteractiveOptionPicker for choices, SeatSelectionPicker for seat selection...",
include_schema=True,
include_examples=True,
allowed_components=["InteractiveOptionPicker", "SeatSelectionPicker", "BookingStatus"]
)
With this generated system instruction, the LLM is grounded in the schema layout and knows exactly how to formulate component updates that the Android client is capable of rendering.
Natively rendering A2UI with Jetpack Compose
To render these component trees natively on Android, use the new Jetpack Compose A2UI Renderer library.First, add the dependencies to our module's build.gradle.kts file:
// android/feature/trip/booking_assistant/build.gradle.kts
dependencies {
implementation("androidx.a2ui:a2ui-model:1.0.0-alpha01")
implementation("androidx.a2ui.compose:compose-runtime:1.0.0-alpha01")
implementation("androidx.a2ui.compose:compose-ui:1.0.0-alpha01")
implementation("androidx.compose.material3:material3-a2ui:1.0.0-alpha01")
}
Each component class in the catalog (such as BookingStatusComponent) defines how to map the properties received from the JSON payload into a Jetpack Compose composable function.
Register the custom components in a catalog:
// android/feature/trip/booking_assistant/src/main/kotlin/com/example/jetpacker/feature/booking_assistant/CustomBookingAssistantCatalog.kt
import androidx.a2ui.compose.ui.A2uiCatalog
fun bookingAssistantCatalog(): A2uiCatalog {
return A2uiCatalog(
catalogId = "https://example.com/catalogs/booking_assistant/v1/catalog.json",
components = listOf(
InteractiveOptionPickerComponent(),
SeatSelectionPickerComponent(),
BookingStatusComponent()
)
)
}
Tip: Jetpacker implements custom components (InteractiveOptionPicker, SeatSelectionPicker, BookingStatus) tailored for booking flows. If your agent uses standard elements (such as text, cards, buttons, rows, columns, checkboxes, and date-time pickers), material3-a2ui also provides materialA2uiBasicCatalogV1(...), giving you ready-to-use Material 3 implementations without writing any custom components.
Note: To keep the backend and mobile client aligned, both rely on the same catalog definition ID (https://example.com/catalogs/booking_assistant/v1/catalog.json). If you add or modify properties on the backend catalog, you must increase the version number, and update the matching Kotlin component class to prevent parsing errors.
In the BookingAssistantViewModel, process the A2UI messages using the A2uiMessageProcessor and update our active surfaces:
// android/feature/trip/booking_assistant/src/main/kotlin/com/example/jetpacker/feature/booking_assistant/BookingAssistantViewModel.kt
import androidx.lifecycle.ViewModel
import androidx.a2ui.model.processor.A2uiSurfaceModel
import androidx.a2ui.compose.ui.A2uiMessageProcessor
import kotlinx.coroutines.flow.StateFlow
class BookingAssistantViewModel : ViewModel() {
private val messageProcessor = A2uiMessageProcessor(
catalogs = listOf(bookingAssistantCatalog())
)
val activeSurfaces: StateFlow<List<A2uiSurfaceModel>> = messageProcessor.activeSurfaces
init {
viewModelScope.launch(Dispatchers.Default) { processor.collectMessages() }
}
// ...
}
In the Compose screen, collect these surfaces and render each one using the official A2uiSurface composable from androidx.compose.material3:material3-a2ui. A2uiSurface automatically handles reactive component state observation, Material 3 loading indicators, error fallbacks, and animated transitions between updates:
// android/feature/trip/booking_assistant/src/main/kotlin/com/example/jetpacker/feature/booking_assistant/BookingAssistantScreen.kt
import androidx.compose.runtime.Composable
import androidx.compose.runtime.collectAsState
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.items
import androidx.compose.material3.a2ui.A2uiSurface
@Composable
fun BookingAssistantScreen(
viewModel: BookingAssistantViewModel,
modifier: Modifier = Modifier
) {
val activeSurfaces by viewModel.activeSurfaces.collectAsState()
LazyColumn(
modifier = modifier.fillMaxWidth(),
verticalArrangement = Arrangement.spacedBy(16.dp)
) {
items(activeSurfaces) { surfaceModel ->
Card(modifier = Modifier.fillMaxWidth()) {
A2uiSurface(
surfaceModel = surfaceModel,
modifier = Modifier.fillMaxWidth().wrapContentHeight()
)
}
}
}
}
You will now see several UI surfaces generated by our agent running in the backend:
A well-designed booking assistant that relies on UI instead of text to interact with the user.
Bringing it all together
By hosting agent workflows in the cloud and using the AG-UI and A2UI protocols together, we can build dynamic, native Android interfaces driven directly by AI models. AG-UI establishes the real-time bidirectional streaming channel for messages and lifecycle events, while A2UI enables the cloud agent to dynamically describe interactive UI components, keeping the client application perfectly decoupled from the step-by-step backend orchestration logic.
Check out the full source code for Jetpacker on GitHub, and watch the video Build Intelligent Android apps with Google’s AI to learn more about how to integrate agentic workflows directly into your app.
Check out the other parts of this blog post series:▪️ Part 1: Introduction of the app and a high-level overview.
📱 Part 2: On-device intelligence. Dive deep into ML Kit’s GenAI APIs and Gemini Nano to build privacy-first features like itinerary summarization, receipt parsing, and local audio processing.
☁️ Part 3: Hybrid and cloud reasoning. Explore how to use Firebase AI Logic to ground LLM answers in real-world data like Google Maps and web context.
⚙️ Part 4: System integration. Integrating with the Android intelligence system using AppFunctions.
🤖 Part 5 (this post!): In-app agentic workflows. Extend the app with end-to-end booking assistants powered by A2UI and ADK.
Interested in more on Android Development? Follow Android Developers on YouTube or LinkedIn!
All code snippets in this blog post follow the following copyright notice:
Copyright 2026 Google LLC.
SPDX-License-Identifier: Apache-2.0October 12th 2026, 3:05 am
Introducing the AndroidX Security State Libraries: A Unified View of Device Security
Android Developers Blog
Posted by Maunik Shah, Staff Software Engineer, Alec Garcia, Software Engineer, and Joseph Yong, Technical Program Manager
At Android, we are constantly working to provide developers and enterprise partners with the data they need to keep devices protected. Today, we're thrilled to announce the stable release of the AndroidX Security State version 1.1.0 and Security State Provider version 1.0.0 libraries which provides a centralized mechanism designed to bring further transparency to the comprehensive security posture and pending updates across the Android ecosystem.
Whether you develop security-critical, consumer-facing apps (such as banking, fintech, or healthcare) or Mobile Device Management (MDM) solutions, these libraries enable you to programmatically verify the security state of the device per component. Rather than relying on a coarse, monolithic Security Patch Level (SPL), you can evaluate true component-level protection and whether remediations are actively pending via the androidx.security.state library. For OEMs and Over-The-Air (OTA) client developers, the companion androidx.security.state.provider library allows you to expose update availability via standardized mechanisms.
Understanding Security Patch Levels (SPL)
As Android has evolved to deliver rapid, independent component updates through modular systems like Google Play system updates, relying on a single SPL build property is no longer the best way to determine a device's true security posture. To provide component level visibility, the Security State libraries provide APIs for three distinct patch levels:- Device SPL (DSPL): The security patch level currently installed and running on the device for specific system components, queried from device properties and configs without network calls.
- Published SPL (PSPL): The latest patch level officially published in the Android Security Bulletin for those components.
- Available SPL (ASPL): The patch level ready to be downloaded and installed on the specific device, queried asynchronously via inter-process communication (IPC) with on-device update clients.
- System: The core Android operating system, updated via standard/OEM system OTA updates.
- System modules: Modular OS subsystems updated seamlessly in the background via Google Play system updates (Project Mainline).
- Kernel: The foundational layer connecting the device's hardware and software, evaluated via Long-Term Support (LTS) release versions (such as 5.15.159 or 6.1.91) rather than monthly calendar dates.
Rather than taking an all-or-nothing approach to device access, developers and enterprises can combine DSPL, PSPL, and ASPL to make smart, contextual security decisions. For example, a banking or enterprise app can compare a device's current security patch (DSPL) against pending updates (ASPL) before initiating sensitive workflows like high-value payments or credential enrollment. If an update is waiting to be installed, developers and enterprises can require the user to update their device first. For even finer control, developers and enterprises can query whether specific high-risk vulnerabilities (CVEs) have been patched on the device, such as verifying that critical NFC or Bluetooth fixes are in place before authorizing tap-to-pay or proximity data sharing.
High-level flow
For app developers and enterprise management
Client applications can use theandroidx.security.state library to make informed, context-aware decisions:
- Synchronous Posture Checks (DSPL): Apps can immediately inspect the installed patch levels of the system, system modules, and kernel on app launch and compare with PSPL to verify whether the device meets an organization's required security baseline before unlocking sensitive corporate resources or biometric access.
- Pending Update Prompting (ASPL): Instead of immediately blocking an employee whose device is slightly behind on patches, enterprise apps can query ASPL to check if a pending system update or Google Play system update is staged and ready to install. If so, apps can display tailored in-app guidance directing the user to System Settings to complete the installation.
- Vulnerability-Level Auditing (CVEs): For high-assurance use cases, the library provides ability to download device-specific vulnerability reports from Open Source Vulnerabilities (OSV) to programmatically audit whether specific, critical CVEs have been resolved on the device.
For OEMs & update clients: Standardizing update availability
The companionandroidx.security.state.provider library establishes a standardized, Android IPC mechanism for update clients to report update availability directly on the device. Historically, even if proprietary OTA clients surfaced update availability, this information was siloed and not queryable by third-party applications. Going forward, apps can access ASPL details through a single, unified API, regardless of whether the update is delivered via an OEM’s dedicated OTA client or Google Play, as long as it is provided by the update client.
- Google Play system updates already expose ASPL across GMS Android devices.
- Google Over-The-Air (GOTA) has also been onboarded and we are working with OEMs worldwide to onboard their OTA clients to this standardized framework.
Incorporating bulletin-level data
Beyond a single SPL string, the Security State libraries provide clarity on what that patch level actually means for the device. By integrating with the Open Source Vulnerabilities (OSV) database to obtain Android Security Bulletin data, the libraries can look deeper than ever before. Instead of just asking if a specific threat, such as a CVE entry, is blocked, this data also allows the libraries to provide the “effective” and granular security state of the device.Here are two ways this approach benefits enterprises and Android OEMs:
- Sometimes, a monthly security update does not contain any new threats for a specific component. In this case, the libraries automatically increments the security level for that component to reflect its "effective" security state. This ensures that a device is accurately credited for being fully protected against all known security threats.
- A new feature introduced in Android 17 allows OEMs to declare specific security fixes that have been applied above the SPL via a Supplemental Patches XML file. This feature allows OEMs who backport specific security fixes to immediately prove device compliance without having to wait for a full monolithic SPL bump, ensuring continuous patching efforts are properly credited. The Security State libraries surface this granular information to apps and services, ensuring that continuous patching efforts are recognized the moment they are implemented.
Get started
The Security State Libraries are built to empower the entire Android ecosystem.- App Developers & MDMs: To start protecting your users and evaluating real-time patch posture, explore the official Understand device security state guide.
- OEMs and Update Clients: Onboard your update clients to expose ASPL using the AndroidX Security State Provider library. Claim immediate credit for backported patches by publishing Supplemental Patches XMLs.
- Release Notes: Check out the official AndroidX Release Notes for Security-State and Security-State-Provider libraries for complete changelogs and API signatures.
We value your feedback! Please try out the libraries and let us know your thoughts or report any issues on the public Android Issue Tracker.
October 12th 2026, 3:05 am
Land your apps on Googlebook with adaptive development
Android Developers Blog
Googlebook introduces a new category of laptops built on a shared Android foundation. High-performance hardware from partners such as HP, Dell, Lenovo, Acer, and Asus, combines mobile convenience with desktop power. Googlebook offers high-resolution OLED touchscreens, dedicated keyboards, and precision trackpads with all-day battery life and OS-level Gemini Intelligence. With Googlebook, users can transition fluidly from quick interactions on their phones to rich, immersive sessions on their laptop.
Bringing your app to Googlebook opens up valuable opportunities for you across the Android ecosystem. Google Play highlights optimized titles with dedicated badging, enhanced search, and featured spots across curated store homepages. Delivering this level of quality also prepares your app for the Apps Experience Program, where you can enroll to unlock a new program rate card designed to drive business growth. Even better, when users set up their new Googlebook using their Android phone, optimized apps are prominently highlighted for easy transfer, giving your app day-one presence on their new device.
The best part? You don't need to build a separate app from the ground up to take advantage of this reach. Adaptive development is how modern Android apps naturally scale across large displays, new device postures, and emerging form factors. If your app already embraces adaptive layouts, it is primed for Googlebooks. By building on your existing foundation of adaptive UI, window size classes, and multi-input support, you can deliver an optimized experience.
Anchor your app in desktop fundamentals
On a laptop, your app operates within a desktop environment where user expectations shift toward higher information density, precision input, and active multitasking. Following desktop development and design guidance provides the principles needed to make the most of this experience. Instead of simply stretching mobile interfaces across a wide screen, an adaptive layout reorganizes content into functional groupings.
Adopt a multi-pane architecture to allow your UI to expand, reflow, or reveal richer detail as window boundaries change. With Navigation 3, you can implement adaptive scene strategies to coordinate multi-pane layouts directly from your back stack. Use ListDetailSceneStrategy and SupportingPaneSceneStrategy to enable side-by-side layouts when expanded window space is available. Scene decorators let you wrap screens with persistent desktop navigation rails. Pair these patterns with layout primitives like Grid and FlexBox, and soon alongside experimental MediaQuery and Styles APIs, to organize complex content and adjust visual styles dynamically for desktop displays.
In free-form desktop windowing, app windows can be resized dynamically at any time. Your layout decisions should respond directly to the available window space using window size classes rather than the physical display dimensions.
Desktop design also accounts for ergonomic viewing distances and precise pointer targets. Adjust your type scale for comfortable viewing across larger displays, set layout max widths to keep line lengths readable, and define explicit click targets to prevent misclicks. Explore complete design patterns in our design principles guide and discover real world inspiration in the desktop design gallery.
Deliver differentiated experiences for Googlebooks
Once your core layout is adaptive, you can enrich your app with differentiated features that take full advantage of a desktop environment. Everyday productivity in these setups relies on versatile input methods. Jetpack Compose natively supports physical keyboard navigation and pointer selection. Elevate your app’s usability by integrating contextual cursors that provide visual feedback for text entry, pane resizing, and tool selection. Implement right click context menus and hover states; make your shortcuts discoverable through the Keyboard Shortcuts Helper.
On Googlebook, apps run in free-form windows where users can tackle multiple tasks simultaneously. Unlock side-by-side workflows by enabling multi-instance support, giving users the ability to launch independent windows for comparing content or managing multiple documents. Pair this with drag and drop to let users move text, images, and files fluidly between windows or even drop items onto an empty workspace to spin up a new task.
Go all in and customize your window frame. In desktop windowing, apps include a caption header bar that you can style with custom backgrounds, search bars, or tabs while respecting system window controls.
Beyond individual app windows, Continue On keeps experiences connected across phones, tablets, and Googlebooks with bidirectional handoff that lets users start a task on one screen and pick up seamlessly on another. Passing state through HandoffActivityData preserves context such as document position or active tabs, with optional web fallbacks to ensure smooth transitions.
Complement this by surfacing actionable information at a glance with customizable widgets. And, as you refine your app experience, benchmark against our comprehensive desktop app quality guidelines.
Developers are already bringing these patterns to life across the ecosystem. When bringing Notability to Googlebook, prior investments in tablets and foldables gave the team an immediate head start. Because their layout already relied on window size classes and adaptive scene strategies, their canvas and toolbars reflowed naturally during window resizing, while existing keyboard and trackpad support carried straight over."We had already been targeting first-class experiences for tablets and foldables," explains Ryan Shea, Android Engineering Manager at Notability. "So by the time Googlebook came along, scaling Notability up to a laptop-class experience was mostly turning a dial we had already built. That left us free to spend our time on the things that only make sense on a bigger screen or with the newer APIs, like Continue On, which hands a note off from your phone to the laptop, and optimizing the side-by-side app experience for studying."
Accelerate your workflow with dedicated tooling
Testing and optimizing your app for Googlebook fits naturally into your existing development workflow.
With the desktop emulator in Android Studio, you can run a virtual desktop environment directly on your workstation to test free-form window resizing, verify multi-instance interactions, and debug mouse, trackpad, and keyboard interactions. Download Android Studio Canary to set up your virtual device today.
Help speed up your layout modernization with AI-assisted development. The adaptive skill gives your AI agents the necessary context to help refactor mobile layouts into responsive Compose containers automatically. Install the skill directly through the Android CLI to streamline your implementation.
Realize new possibilities on Googlebook
The Googlebook lineup marks an exciting new chapter for the Android ecosystem, giving your apps a premium platform to deliver richer, more capable experiences. By building adaptively, a single codebase ensures your app looks and performs optimally across phones, foldables, tablets, and Googlebooks while unlocking elevated visibility and badging across Google Play. Explore documentation at our Googlebook developer hub, review the desktop design guide, and start building for Googlebook today!
October 12th 2026, 3:05 am
Build your way: Use any AI agent of your choice in Android Studio
Android Developers Blog
Posted by Matthew Warner, Product Manager, Android Developer Experience
AI-powered developer tools have become an essential multiplier for engineering productivity, with teams adopting specialized AI coding agents, custom enterprise harnesses, and autonomous tools. It’s important for you to be able to build Android apps in the way that works best for you and your team, and agentic Android development is more open and flexible than ever before.
Last year, Android Studio opened up to any AI model. Today, we’re taking the next step by introducing support for your choice of coding agents. With our new Bring Your Own Agent (BYOA) feature, you can seamlessly integrate your preferred coding agent into Android Studio—featuring Anthropic’s Claude Agent, Open AI’s Codex, and Google’s Antigravity—and supercharge it with Android Studio’s AI-optimized infrastructure and tool support.
Your agents, your AI plan
BYOA pairs your favorite agent with IDE-native intelligence, making it faster, more accurate, and more cost-effective. BYOA is available in the latest Android Studio Canary with benefits including:
- Codebase awareness and token efficiency: Android Studio provides the full project graph, build setup, and platform details directly into your agent using Agent Client Protocol (ACP) . The agent can then filter to relevant files or details for efficient token usage, lower latency, and sharper answers.
- Seamless workflow continuity: Transition smoothly between multiple conversational agent prompts and Android Studio's purpose-built tools, keeping your flow state intact as you effortlessly jump between tasks.
- Agent flexibility: Connect any ACP-compliant agent directly into Android Studio, and sign in with your plan. If one agent runs out of quota or isn’t meeting your performance expectations, you can have another agent take over.
- Native tool injection: We wire up build diagnostics, UI tools like Jetpack Compose Previews, Android SDK tools, and Android emulator control so your agent has access and can test, diagnose, and execute directly in Android Studio.
Powerful, capable, and reliable coding agents
Agents can plan and execute complete technical workflows directly in your environment, unlocking powerful use cases:
- Execute in the environment: Read, write, and edit files, run shell commands, run tests, and search the web.
- Delegate to subagents: Break down complex projects by spawning specialized agents for subtasks like code review or testing.
- Stay in control: Granular permissions let the agent act on its own for routine work, and pause for your approval on riskier actions.
- Persist context and configuration: Maintain long-running sessions and automatically load project skills, slash commands, and memory.
Agents running in Android Studio also benefit from Android skills and the Android Knowledge Base, ensuring they have access to the latest Android best practices. And if you want to learn more about how agents impact model performance, read more about our latest updates to Android Bench.
Using Gemini with Google Antigravity
Many developers have been using Gemini directly in Android Studio through the built-in agent, and we will continue to offer this experience in Android Studio. However, for the best experience with Gemini, we recommend selecting the Google Antigravity agent for access to the latest Gemini models such as Gemini Flash 3.8, along with increased AI usage quota. You can also login to the Google Antigravity agent with your Google AI Pro or Ultra plan to take advantage of your benefits in Android Studio, or pay per token rates with a Gemini API key.
Selecting the Google Antigravity agent
If your organization is using Gemini Enterprise, you can continue to use the built-in agent or the Antigravity agent. In either case, your organization continues to benefit from the added security and privacy of Google Cloud.
Get started
BYOA support is rolling out in preview starting with the canary release of Android Studio Rabbit 2 featuring commonly used agents like Google Antigravity, Claude Agent, and Codex. Both enterprise and consumer AI plans are supported - subject to the agent provider. To connect an agent, follow these steps:
- Update Android Studio: Ensure you are running the latest from the canary release channel.
- Connect your agent(s): In the agent window, select one of the agents (Claude Agent, Codex, or Antigravity) and sign-in or provide an API key. Additional agents can be found in the registry Settings > Tools > AI > Agents
- Explore the docs: Check out our preview release note here.
Your feedback is essential as we continue to refine the AI experience in Android Studio. If you find a bug or issue, please file an issue. We can’t wait to see what you build!
October 12th 2026, 3:05 am
Device Streaming and Android skills - available in Android CLI
Android Developers Blog
As Android developers, you have many choices when it comes to the agents, LLMs, tools, and command-line interfaces (CLI) you use for app development. Our goal is to help you build beautiful, high-quality Android apps, no matter how you choose to build. We’re announcing updates to our Android CLI command-line tooling, including the ability to access real devices through Android Device Streaming. We’re also sharing more Android skills, and giving you a deep dive into the Wear OS Compose Material 3 skill.
Android CLI for command-line development
Android CLI is our tool to make command-line interface Android development easier. It supports any AI agent or tool in building more efficiently for Android.
Along with the android-cli skill, your agents use Android CLI to create, build, test, and manage Android projects, help you set up the development environment, create and run emulators, and execute test runs.
Android Device Streaming now available in CLI
It’s important to test your app on real devices to catch issues that are hardware- or OS-specific, but sometimes you don’t have access to the ones you need. Android Device Streaming gives you access to real physical devices, remotely. Your agent can now use Android Device Streaming anywhere, through Android CLI.
The agent can interact with physical devices (as if they were plugged in over USB) over a secure ADB over SSL connection. This enables spinning up devices, deploying builds, collecting logs and traces, and even capturing screenshots headlessly—all through the terminal.
To get started, link your project, instruct your agent to list available remote devices and decide which device you want next. Read the documentation to learn more, and see the Android CLI release notes.
Grounding agents with Android skills
To bridge the gap between LLMs’ default knowledge and platform-specific standards and updates, we keep growing our Android skills repository.
Android skills are structured instructions (SKILL.md files) that ground AI agents with our official guidance from developer.android.com. Instead of relying on a model’s training cutoff, skills provide more precise and fresher data, API references and samples, and architectural patterns directly into your agent’s context.
With over 20 skills available, you can now equip your AI agents to handle more complex and specialized development tasks such as:
- Audit Play policy compliance: Audit app manifests, runtime permissions, target SDK levels, and privacy disclosures before submitting your app for Play Policy review.
- Implement Restore Credentials: Implement re-authentication across device setup and cloud restores using Jetpack Credential Manager.
- Android Intent security: Detect and prevent implicit intent hijacking, secure broadcast receivers, and validate PendingIntent declarations.
- Use Android profilers: Diagnose UI frame drops, interpret CPU/memory traces, and query trace data using natural language mapped to PerfettoSQL.
- CameraX: Replace legacy Camera1/Camera2 code with lifecycle-aware CameraX.
- Migrate Leanback to Compose for TV: Modernize Android TV experiences by transitioning from Leanback to Compose for TV.
- Integrate Media3 Cast: Connect Jetpack Media3 media sessions with Google Cast receiver devices and sync playback states.
- Integrate Play Engage SDK: Integrate the Google Play Engage SDK to publish user recommendations and cluster surfaces.
- Set up testing strategy: Configure unit test suites, Compose UI testing rules, and screenshot testing infrastructure.
- Audit R8 configuration: Optimize your app's performance by auditing your R8 configuration.
Our Android skills are thoroughly evaluated. To understand the philosophy and methodology behind this project, as well as why all skills should come with evals, make sure to read Inside Android Skills - Built for deprecation.
Managing skills across projects and individual agent directories is pretty straightforward with Android CLI:
- Install Android CLI
-
Run
android initto install theandroid-cliskill -
To list all available official skills, run:
android skills list -
To install individual skills into a single project root:
android skillsaddwear-compose-m3 --project=. - To update skills, use:
-
android skills update --all -
android skills update wear-compose-m3(for an individual skills)
Skills are designed to be environment-agnostic. From writing code in Android Studio and Antigravity, to pairing with third-party agents like Claude and Codex, our Android skills work across your entire setup.
Skill spotlight: Wear Compose Material 3
Building for Wear OS means distinct design and development decisions: round viewports, rotary input, ambient display mode, minimizing power consumption, preferring TransformingLazyColumn, and using the AppScaffold and ScreenScaffolds containers.
Without explicit guidance, LLMs lack the understanding and knowledge of these distinct patterns that make the Wear apps really stand out and shine.
To help agents with this, we released the Wear Compose Material 3 skill (wear/wear-compose-m3).
Check out this video for more information on how powerful this skill is:
Early adopters are already seeing significant productivity impact with this skill. The engineering team at FotMob used it for tasks like modernizing their existing Wear M3-based app, migrating multiple lists to TransformingLazyColumn with ScreenScaffold content padding, ListHeader titles, SurfaceTransformation on cards and buttons, theme typography, and Wear previews.
The result? The changes compiled successfully and were verified on the emulator for scrolling, rotary, edge morphing and RTL. This enabled the team to delete their legacy wrapper, and all rotary and focus boilerplate.
The skill caught mistakes that the underlying model missed, such as forgetting to forward ScreenScaffold's contentPadding into the list, and using theme typography over hardcoded sp.
“One skill, one afternoon, eight lists migrated and a pile of custom rotary code gone!” - Roy Solberg, Android Tech Lead at FotMob.
Get started today
When you're ready to get started, install Android CLI with just one command. You can learn more about Android CLI by reading the developer documentation, and as well as checking out the latest updates in the Android CLI release notes.
After installing Android CLI, run android init to configure your agent, then browse the latest Android skills available for use and install them with android skills add.
Also check out the Android Device Streaming documentation to learn more about how this feature allows you to access real devices on the cloud inside both Android Studio and via your agents.
October 12th 2026, 3:05 am
Introducing Fast and Reliable Wireless Debugging with Android Debug Bridge (ADB) Wi-Fi 2.0
Android Developers Blog
Wireless debugging on Android is now faster, more reliable, and easier to set up than ever. With ADB Wi-Fi 2.0, we’ve introduced a new server stack and smarter network handling to directly address developer feedback around usability gaps.
How ADB Wi-Fi 2.0 Improves Wireless Debugging
To ensure ADB Wi-Fi 2.0 is even more reliable, we reworked all three core components of the stack: the adb server, the adbd daemon, and Android Studio.
Here are the new features:
- A new server stack (adb): Previously, wireless device connections would sever when network configurations changed or devices were turned off. This meant that connections would drop for common occurrences. With our new mDNS stack, we’ve replaced both Bonjour and legacy mDNS so that your wireless devices more reliably stay connected as you go about your day.
- Smarter network handling (adbd): Previously, the workstation's mDNS client would sporadically drop services. Now, the daemon automatically turns off ADB Wi-Fi when it detects an untrusted network and re-enables itself once running on a user-allowed network.
- Improved discoverability in Android Studio: Previously, Wi-Fi pairing was difficult to find. Now, you simply enable wireless debugging on your phone and it will show in Android Studio’s Device Manager.
With ADB Wi-Fi 2.0, auto-connection success rates improved by 32% and connection speeds increased by 66% for 90% of connections.
Getting Started
You can use ADB Wi-Fi 2.0 on your phone, tablet, Wear OS, and TV. Here’s how to get started:
- Update to Android 17, Android SDK Platform-Tools 37.0.0, and Android Studio Quail 3 or later.
- Ensure your workstation and your Android device are connected to the same Wi-Fi network.
- On your device, navigate to Developer Options and enable Wireless debugging.
- Open the Android Studio Device Manager and click the pair over Wi-Fi icon.
- Scan the QR code with your device or use a pairing code, and you're all set!
For more information, see the documentation or watch the presentation at Android Makers by droidcon 2026.
As always, we appreciate any feedback. If you find a bug or issue, please report it. Also, you can be part of our vibrant Android developer community on LinkedIn, YouTube, or X.
September 9th 2026, 5:29 pm
Leverage Android skills and Gemma 4 in Android Studio Quail 4
Android Developers Blog
Android Studio Quail 4 is now stable and ready for you to use in production.
This is the final stable release for Android Studio Quail. The new features in Android Studio enable you to build premium apps with AI efficiently and effectively. Check out the video below to see the most helpful new features from the last 4 releases that can help improve and speed up your development.
Here is a deep dive into what’s new in Android Studio Quail 4:
Android skills bundled into Android Studio
While LLMs are incredibly capable at generic coding queries, they frequently write incorrect or outdated code when confronted with rapidly evolving Android APIs, platform-specific migrations, or complex configuration structures.To solve this, we bundle Android skills that have been curated by the team who builds Android, directly into Android Studio. Following the open-standard agent skills specification, these are modular, AI-optimized instructions designed specifically to guide LLMs through complex Android workflows. Android skills are now pre-loaded directly into the IDE, so you can start using them without having to manually download additional files.
When you prompt the Android Studio agent, we analyze your prompt and search against the metadata for installed skills, automatically invoking them when they're most relevant. Your agent gains instant domain expertise, applying Google's best practices with less overhead spent on long, manual setup prompts.
Android Studio comes preloaded with 23 curated skills, including:
- Need help upgrading your build? You have the Android Gradle Plugin (AGP) 9 Upgrade skill.
- Want to profile your app for any performance issues? You have the Android Profiler skill.
- Ready for a Jetpack Navigation framework upgrade? You have the Navigation3 skill.
- Adapting your app UI to different Android devices? You have the Adaptive skill.
android skills add --all to quickly get started. If you ever want to disable bundled skills entirely, you can easily opt out via an IDE-wide toggle in Settings.Gemma 4 local model integration (private, secure, and offline AI coding)
Many developers enjoy having access to local models, and Android Studio now natively integrates Gemma 4—Google’s most powerful open model—for AI code assistance without the hassle of manual third-party setup.- System requirements: You can run the smallest models with 12GB of RAM, but machines with 32GB+ RAM will run best. Please refer to hardware requirements.
- One-click management: Simply select Gemma in the Agent model selector and then choose the model you’d like to download, or visit Settings > Tools > AI > Model Providers > Gemma. Android Studio automatically downloads, verifies, and updates the model weights for you.
- Bundled inference engine: We have bundled a lightweight inference engine to run Gemma 4 models directly in the IDE.
- On-device AI agent: Because Gemma 4 features native agentic tool-calling capabilities, you can run complex, multi-file refactoring plans with the agent completely offline. Your source code never leaves your local machine and you never hit token quota limits.
Parallel Agents UX notifications and other enhancements
In Android Studio Quail 2 we brought you agentic multitasking with parallel chats. And now Android Studio Quail 4 brings a several UI enhancements designed to make your AI interactions smoother, faster, and more transparent:- Hyperlinked code symbols in responses: Class names, functions, methods, and file paths mentioned in agent responses are now automatically detected and rendered as clickable hyperlinks.
- Real-time background agent notifications: When multitasking with parallel chats, the Recent Chats panel now provides at-a-glance status indicators. You’ll see a loading spinner when an agent is actively running tools, a red status indicator if an agent is waiting for your input, and a blue badge when a background task has finished and is ready for review.
- Unified Summary of Changes: After the agent completes a multi-step coding task, the separate Task and Walkthrough artifacts are now consolidated into a clean, dedicated Summary of Changes tab, giving you a clear diff and review experience before applying modifications.
- Collapsible thought process rendering: For reasoning models, the agent's step-by-step thinking process is neatly organized into collapsible blocks, keeping your chat conversation easy to scan while allowing you to inspect the underlying logic on demand.
Upgrade for premium AI capabilities
Android Studio gives developers access to a default Gemini model out-of-the-box. We adjust the capabilities of this model dynamically to ensure we're able to provide a great experience at no cost. However, if you want more granular access to Gemini's most powerful models or need additional quota for long coding sessions, you can upgrade your access using one of these 3 routes:- API Key: Use the latest Gemini models, such as Gemini 3.7 Flash, in your development flow as soon as they are available with your Google AI Studio API key. You can also use the API key from other model providers like Anthropic or OpenAI right in Android Studio
- Google AI plan: Developers with a Google AI Pro or Ultra plan can log in with their Google account to automatically unlock premium capacity and higher rate limits. With its expanded capabilities, Gemini can help you with analyzing, refactoring, and planning features across massive codebases.
- Gemini Enterprise: If your organization has access to Gemini Enterprise, Developers can log in to leverage the privacy and security benefits of Google Cloud while using the Android Studio AI agent. This is rolling to select organizations, and is currently available in the latest Android Studio Canary.
A Look Back: The Android Studio Quail Series Recap
The Android Studio Quail 4 release continues our focus on accelerating developer productivity with AI. Check out our previous blog posts to learn more about the new features that recently landed.Android Studio Quail
- App Quality Insights Agent Integration: We kicked off the Android Studio Quail cycle by integrating App Quality Insights (AQI) with Gemini.
- Released in Android Studio Quail (Canary) at Google I/O: We introduced tools built for the agentic era, including Agent Skills, Firebase integration and parallel conversations in Agent Mode, local model support with Gemma 4, Android CLI, peer-to-peer Android Emulator multi-device testing, ADB Wi-Fi 2.0, and native Google Play testing track publishing.
- Parallel Chats: We unlocked concurrent multitasking in the IDE. Developers can open multiple chats as side-by-side Editor Tabs—running a Compose refactor in one tab using Gemini 3.5 Flash while documenting code in a second tab with Gemma 4 in parallel. Active background tasks are easily monitored via real-time progress indicators (loading spinners, paused statuses, and errors) in the Recent Chats sidebar.
- LeakCanary Profiling: We natively integrated LeakCanary directly into the Android Studio Profiler. By lifting and shifting JVM heap analysis off the test device and running the Shark analyzer engine on your host computer, memory leak tracing became five times faster and completely jank-free, backed by "Fix with Agent" AI remediations.
-
Simplified Planning Mode: When using the
/plancommand or switching your conversation to "Planning," the agent steps back to evaluate its logic, mapping out an implementation plan before writing code. -
MCP Marketplace: Navigating to
Settings > Tools > AI > MCP Serversnow lets you easily search, install, and manage Model Context Protocol (MCP) servers straight from the IDE, allowing you to connect your AI agent to external developer tools, registries, and custom databases.
Get Started Today
Android Studio Quail 4 is now available in the stable channel. Ditch the manual configuration, multitask across parallel threads, and build with expert-grounded AI intelligence.As always, your feedback shapes the future of Android development. Please check out known issues or file bug reports and feature requests directly on our official bug tracker.
You can also join our vibrant developer community and stay up-to-date with the latest insights by following us on Instagram, LinkedIn, YouTube, or X. We can't wait to see what you build!
September 3rd 2026, 12:20 pm
Emulator control for adaptive app development
Android Developers Blog
Posted by Rob Orgiu, Developer Relations Engineer, Adaptive Apps, Android
Adaptive app development is fundamental on Android, but making sure everything looks good and every feature works the way it should require multiple tests on multiple devices. Or does it?
Well, yes… and no! While Android Studio is bundled with the Resizable Emulator to let you test layouts manually, there’s a faster, more streamlined way to control form factors directly from your terminal. By leveraging fire-and-forget console commands using the adb emu shortcut, you can execute commands that immediately return control to your invoking shell.
If you have multiple emulators running at the same time, you can target a specific virtual device by passing in the shortcut's serial:
adb -s <serial> emu <command> <parameter>
First things first: Fold and unfold
To test foldable-specific user journeys and layout configurations, you can fold and unfold your emulated device programmatically.
adb emu fold
If your foldable emulator is unfolded, you can fold it to display its smaller screen configuration, powering on the (virtual) external display. To unfold the emulator and power on the internal display, simply run:
adb emu unfold
Now, you can instantly verify that your app preserves its state and that layouts appear exactly as they should on different display sizes.
Rotation, rotation, rotation
Correctly handling orientation changes is a cornerstone of adaptive app development. You can trigger device rotations programmatically to test how well your app handles configuration changes, including state restoration. The following command rotates the device 90° clockwise:
adb emu rotate
Simulating postures using sensors
What about placing the emulator into a specific physical posture, like tabletop mode? The easiest approach is querying for the number of available positions with .
First, list all available sensors and their current status:
adb emu posture
This returns a list of positions similar to the following:
Usage: "posture <posture_id>" 1: closed 2: half-opened 3: opened …
You can then invoke the tabletop posture by using the half-opened ID:
adb emu posture 2
Note: Not all postures are supported by every virtual device. Standard AVD templates like the Pixel Fold or the Resizable AVD only support postures 1 , 2 , and 3 . Attempting to set 4 or 5 on these templates will return a KO: Failed to set posture error.
What about the resizable emulator?
The resizable emulator has the super power to change its size with ease. With theadb emu command, you can move it freely with one command. Before you can do any changes, querying for the available resize presets requires only one call:
adb emu resize-display
This will return the list of available presents:
KO usage: "resize-display <index>" 0: phone 1: unfolded 2: tablet
Now, invoking the resize-display parameter with the wanted ID will resize the emulator to the wanted size:
adb emu resize-display 1
Streamline your testing today
And that's it! By integrating fire-and-forget commands into your command-line workflow, you save a lot of time and resources compared to running multiple emulators simultaneously.
Now is the time to start experimenting. If you haven't used these console shortcuts before, open up your terminal, fire up your emulator, head over to the documentation, and get started today!
August 31st 2026, 1:22 pm
How WhatsApp Upgraded to Secure, Seamless Sign-In for 1 Billion Users with Passkeys
Android Developers Blog
WhatsApp is the world's largest messaging platform, serving billions of users globally. It is the default communication tool for people across diverse regions, connecting users through private, reliable, and secure messaging.
"What excites me most is the sheer scale of WhatsApp's impact. Even a small improvement to WhatsApp touches billions of users worldwide," says Mayank Manuja, an Android Engineer on the WhatsApp Registration and Access team who led the design and implementation of passkey-based authentication for WhatsApp.
Building for an audience of this magnitude requires navigating a vast range of network conditions, device capabilities, and levels of digital literacy. Recognizing the potential early, WhatsApp committed to adopting passkeys in 2023, becoming one of the first major consumer apps to integrate the technology. By implementing passkeys, WhatsApp aimed to provide a fast, phishing-resistant option that significantly reduces user friction while providing robust protection against account takeovers and credential theft.
The Decision to Adopt Passkeys
For WhatsApp, offering multiple access methods is key to making it easier for users to stay connected and regain access when needed. Passkeys offer users a streamlined, one-tap login experience that eliminates phishing risks and functions reliably even in regions where OTP message delivery can be inconsistent.
Underneath, passkeys leverage public-private key cryptography to replace manual entry with biometric or screen lock authentication. This workflow drastically improves sign-in speeds by reducing the process to a single tap via a unified, bottom-sheet interface that keeps users engaged within the app's context. The benefits are twofold: passkeys offer users a streamlined login experience while simultaneously providing robust, native protection against phishing attacks. Crucially, they function reliably even in regions where traditional SMS OTP delivery can be inconsistent.
How passkeys are saved and used to authenticate using public-private key cryptography
Having robust and diverse account access methods ensures that users are never locked out of what matters most to them.
Client-Side Integration
From the WhatsApp developer perspective, the Credential Manager API provided a clean, unified interface that abstracted away the complexity of underlying credential providers. Once initial integration flows were mapped out, the API surface became straightforward, with credential creation and retrieval following well-defined request and response patterns. Find the implementation guide in the Android developer documentation.
While the happy path worked from the start, navigating a diverse user base across OEMs, multiple Android versions, and varied device configurations (such as PIN-only versus biometric, or Android 13 versus 14+) surfaced unprecedented edge cases. These included users without a screen lock, unexpected exception types, outdated Play Services, and inconsistent credential provider behavior.
To overcome these hurdles, the WhatsApp and Google teams collaborated deeply and tackled several challenges:
- Optimizing the credential lookup flow: The initial lookup flow exhibited poor latency, particularly for users who had not yet created a passkey. Since the majority of WhatsApp users fall under this bucket in early stages, this added noticeable delay to nearly every sign-in. By instrumenting the call path and identifying bottlenecks together, WhatsApp significantly fastened up the process, achieving performance gains that ultimately benefited the entire Android ecosystem.
- Handling transient states: WhatsApp built a comprehensive error-handling layer to navigate device-specific hurdles such as password manager availability, screen lock not configured, intermittent connectivity issues, incompatible hardware, outdated play services, categorizing exceptions into recoverable and terminal states. This allowed for graceful degradation, if a passkey flow could not complete, the system safely fell back to traditional authentication without leaving the user in a broken state.
- Navigating OS-specific exceptions: When telemetry revealed device-specific hurdles such as GetPublicKeyCredentialDomException (Failed to decrypt credential) on certain Android 13 devices, and CreatePublicKeyCredentialDomException (Unable to get sync account) during passkey creation on Android 14, Google and the WhatsApp team investigated the root causes and implemented platform-level improvements to ensure smoother creation flows. You can find the comprehensive error guide here which lists common error codes and descriptions related to Credential Manager, and provides some information about their causes.
Note: For further guidance, explore the Passkeys best practices blog to learn how to optimize the user experience when adopting passkeys.
Refining the User Experience
Because passkeys were an entirely new concept in early 2023, there were no established patterns for prompting their creation. Through extensive A/B testing, WhatsApp developed a contextual framework targeting users who would benefit most. This strategy continuously evolved: as Android OS flows matured into a streamlined, single-screen experience, WhatsApp simplified its own prompts to avoid redundant or confusing UI.
WhatsApp's streamlined, single-screen passkey creation flow
Server-Side Architecture and Cross-Platform Hurdles
On the backend, WhatsApp's server implements the standard WebAuthn/FIDO2 ceremonies. The backend is written in Erlang and calls the Rust webauthn-rs library through a native interface. This Rust library handles signature verification and credential parsing, allowing the internal code to remain focused on orchestration, storage, and product rules like eligibility, rate-limiting, and credential lifecycle.
The server architecture orchestrates these core ceremonies through four primary entry points, paired into Begin and Finish sequences for both Registration and Authentication:
1. Passkey registration
This sequence handles issuing creation options to the client, verifying the attestation once the client acknowledges successful creation, and securely persisting the credential.
The server & client interaction architecture during passkey registration
Erlang: Begin Registration
begin_registration(UserId) ->
Existing = list_credentials(UserId),
%% reuse the existing user handle, or mint a new one
{UserHandle, IsNew} = user_handle(Existing),
%% returns the client creation options and the server-side challenge state
#{client_safe := CreationOptions, server_only := ChallengeState} =
webauthn:start_registration(UserId, UserHandle, rp_config()),
%% excludeCredentials: the user's existing credential IDs, so the device won't re-enroll one
Options = with_exclude_credentials(CreationOptions, credential_ids(Existing)),
store_challenge(UserId, ChallengeState), %% short TTL
IsNew andalso reserve_user_handle(UserId, UserHandle),
Options.
- Identify the user: The server first checks for any existing credentials to either reuse an existing user handle or generate a new one.
- Generate options and challenge: It calls the WebAuthn library to generate the creation options for the client and a secure challenge state for the server.
- Prevent duplicates: It explicitly excludes the user's existing credential IDs so that the device does not accidentally re-enroll a passkey that is already registered.
- Store challenge: The server temporarily stores the challenge with a short time-to-live (TTL) and sends the options back to the client device.
Erlang: Finish Registration
finish_registration(UserId, Attestation) ->
ChallengeState = get_challenge(UserId), %% must exist and be unexpired
#{credential_id := CredId, public_key := PubKey} =
webauthn:finish_registration(Attestation, ChallengeState, rp_config()),
ok = index_credential(CredId, UserId), %% map credential_id -> account
case multi_passkey_enabled(UserId) of
true -> add_credential(UserId, CredId, PubKey); %% append (oldest evicted past the cap)
false -> replace_credential(UserId, CredId, PubKey) %% single-passkey mode
end,
notify_client(UserId, {passkey_created, CredId}),
ok.
- Retrieve challenge: The server retrieves the stored challenge, ensuring it still exists and hasn't expired.
- Verify attestation: It passes the client's response (Attestation) and the challenge to the WebAuthn library to verify the request and extract the new credential ID and public key.
- Index the credential: The new credential ID is mapped directly to the user's account for fast lookup later.
- Save and manage limits: Depending on whether the multi-passkey feature is enabled, the server will either append the new credential to the user's list (evicting the oldest if a cap is reached) or replace the existing one in single-passkey mode.
2. Credential Authentication
Similar to creation, the app server handles the authentication flow by orchestrating the login sequence. This includes verifying the assertion after successful client authentication, and dynamically updating stored credentials whenever WebAuthn signals a refresh is necessary.
Erlang: Begin Authentication
begin_authentication(UserId) ->
Credentials = list_valid_credentials(UserId),
#{client_safe := RequestOptions, server_only := ChallengeState} =
webauthn:start_authentication(Credentials, rp_config()),
store_challenge(UserId, ChallengeState), %% short TTL
RequestOptions.
- Fetch valid credentials: The server looks up all currently valid credentials associated with the user.
- Generate challenge: It uses those credentials to build request options for the client and generates a new server-side challenge.
- Store and return: Just like in registration, the challenge is saved temporarily, and the request options are passed to the client app.
Erlang: Finish Authentication
finish_authentication(UserId, Assertion) ->
ChallengeState = get_challenge(UserId),
Credentials = list_valid_credentials(UserId),
case webauthn:finish_authentication(Credentials, Assertion, ChallengeState) of
#{user_verified := true, credential_id := CredId, needs_update := NeedsUpdate} = Result ->
%% webauthn tells us when the stored credential should be refreshed
NeedsUpdate andalso refresh_credential(UserId, CredId, Result),
mark_credential_used(UserId, CredId),
{ok, CredId};
_ ->
{error, not_allowed}
end.
- Verify assertion: The server retrieves the stored challenge and valid credentials, then asks the WebAuthn library to verify the client's Assertion.
- Refresh if needed: If the user is successfully verified, the server checks a needs_update flag. The WebAuthn library uses this flag to signal if the stored credential state needs to be refreshed on the server.
- Finalize: The server marks the credential as used and successfully completes the login process.
To know more about server registration, follow the integration guide here.
Advanced Architectural Considerations
Implementing passkeys on the server at scale presented unique challenges, particularly concerning account architecture and device synchronization. Ashish Choudhary from the WhatsApp backend team highlighted the primary hurdles they faced:
- Migrating to multiple passkeys per account: WhatsApp's legacy server logic was deeply intertwined with the assumption of a single credential per user. To support modern multi-device realities, they engineered a bounded list system that intelligently evicts the oldest credential once a limit is reached. To ensure absolute stability, this major structural shift was rolled out gradually through rigorous experimentation.
- Balancing the credential lifecycle: Managing credential validity required a delicate touch. Invalidating credentials too aggressively forces needless re-enrollments, while being too lenient lets stale credentials pile up. WhatsApp solved this by implementing balanced lifecycle states to maintain tight security without frustrating users, complemented by automated background cleanup for inactive passkeys.
Rethinking Cross-Device Synchronization
This robust multi-passkey architecture also allowed WhatsApp to completely rethink cross-platform usability. The standard WebAuthn cross-device flow requires scanning a QR code on one device and authenticating over Bluetooth on another. However, WhatsApp found the Bluetooth dependency unreliable, and users often confused the new QR codes with the existing WhatsApp Web linking process.
Instead of forcing a fragile cross-device transport mechanism, WhatsApp allows users to hold passkeys natively across multiple ecosystems such as Google Password Manager on Android and iCloud Keychain on iOS. When users migrate to a new platform, they simply generate a fresh passkey during their next sign-in. This approach is completely frictionless for the user and operates seamlessly on top of the new multi-passkey server infrastructure.
Looking Ahead
Since launching passkeys, WhatsApp has witnessed robust organic adoption across its vast user base. By transforming the traditional multi-step sign-in process into a single, frictionless biometric gesture, the app has dramatically improved the user experience. Building on this momentum, WhatsApp is now expanding passkey utility beyond initial sign-ins, exploring seamless in-app re-authentication for sensitive account actions like passkey-encrypted backups.
Looking ahead, WhatsApp is actively collaborating with platform partners to pioneer lower-friction credential creation paths, anticipating that barriers to entry will naturally diminish as device biometric capabilities expand.
Recommendation for Developers Building at Scale
For developers preparing to integrate passkeys at scale, the WhatsApp team shares these critical recommendations:
- Invest in an error taxonomy early: Categorize the wide variety of Credential Manager exceptions into recoverable versus terminal states, and define clear, graceful fallback paths for each scenario.
- Understand your eligibility funnel: Instrument device capability checks such as screen lock presence, biometric hardware, and Play Services versions and design flows to proactively exclude ineligible users rather than failing mid-flow.
- Prepare your app for fallback: Use passkeys as an optimal primary authentication method for capable devices, but always retain traditional methods as a reliable, universal fallback.
- Plan for OS version fragmentation: Passkey behavior can differ across operating systems. Test thoroughly on Android 13, 14, and 15+, and account for OEM-specific variations in the credential selection UI.
- Upsell contextually and educate: Present passkey creation naturally during security-relevant actions. Clearly emphasize the value proposition (speed and security) using accessible language to drive user adoption.
- Monitor proactively: The ecosystem evolves with every OS update. Continuously track latency and error patterns to stay ahead of shifting device landscapes.
Get Started with Passkeys and Credential Manager
Get hands on with passkeys and Credential Manager on Android using our integration guide and public sample code.
If you have any questions or issues, you can share with us through the Android Credentials issues tracker.
August 27th 2026, 4:00 pm
Elevating app quality: Reducing memory usage and improving device migration
Android Developers Blog
Posted by Raghavendra Hareesh Pottamsetty, GM, Google Play Developer & Monetization
Maintaining a healthy Android ecosystem is a shared commitment where every app and game has a role to play. To help you deliver the premium experiences users expect, Google Play is introducing two new quality requirements: one focused on reducing app memory footprint, and another on providing a secure, seamless device migration experience.
First, to help developers navigate industry-wide hardware constraints and Android's broader memory limits, Google Play is establishing new performance thresholds.
Second, as part of our broader commitment to elevate app quality, we are introducing a new onboarding standard to simplify and secure login during device upgrades.
Reducing app memory usage and optimizing code
The mobile industry is navigating significant hardware supply constraints that are altering device memory availability that over time can negatively impact the user experience. Android is addressing this challenge head-on with broader memory limits that aim to protect the overall user experience from apps using excess memory and causing system-wide slowdowns.
Building on this, today Google Play is establishing performance thresholds to help developers ensure their apps continue to deliver the premium experience users expect. This includes new thresholds across dynamic memory usage, bitmap usage, and code optimization to prevent unexpected on-device performance throttling and app terminations.
- Dynamic memory usage (anonymous RSS + swap): This tracks the memory used for your app's private data storage, including both active and compressed memory. It excludes files stored on the device, such as code or assets. We will assess this usage across different app states (like when your app is in use or running in the background) and device performance categories.
- Bitmap memory usage: This evaluates the memory consumed by bitmaps. While bitmaps occupy memory when your app is in the foreground, they should not be held in memory for extended periods of time in non-visible app states such as background and cached.
- Optimized DEX code: A well-optimized Android App Bundle uses less memory, starts faster, reduces ANRs, and improves rendering and runtime performance. To ensure an optimized footprint, apps published on Google Play apps published on Google Play must be optimized with a minimum of 25% coverage across optimization, shrinking, and obfuscation using a tool such as R8 or any other shrinking tool.
Review the thresholds and technical details to better understand applicability differences specific to apps and games, RAM buckets, and process states.
New tools to help you take action
To enable you to proactively discover, investigate, and optimize your app or game to meet the new bad behavior thresholds, we’ve already begun rolling out new tools in Play Console to get you started.
- Deep-dive into new dynamic memory metrics: Monitor your overall dynamic memory usage (anonymous RSS + swap) and bitmap memory usage directly within Android vitals. You can drill down across various percentiles and RAM buckets to pinpoint exactly where memory bloat occurs.
- Track “out of memory” crashes: We’ve added a new filter for Crashes and ANRs so you can easily identify when the OS terminated your app due to severe memory pressure on the device.
- Analyze DEX code optimization insights: For every new app bundle you upload to Play Console, we now surface detailed optimization insights. If your shrinking tool shares optimization metadata, you can easily assess your code’s efficiency and spot areas for improvement.
- Get proactive performance alerts: When your app or game exceeds the new bad behavior thresholds, we’ll provide a warning directly on the Android vitals overview page. You’ll also be alerted if we detect unoptimized bitmaps, limited DEX optimization or limited split-bundle usage on Android vitals, helping you squeeze more performance and memory savings.
Later this year, you can expect additional diagnostic tools, including metrics on how long your app spends in each state and deeper insights into the Android Memory Limiter, a feature that prevents individual apps from using too much device memory. Through our ongoing investment in these enhancements, our goal is to help you continuously optimize your footprint and elevate the experience you provide your users.
Enforcement timeline
Starting in February 2027, apps and games must meet their respective bad behavior thresholds for Memory usage (Anonymous RSS + Swap), Bitmap memory usage and DEX code optimization. Similar to existing Android vitals metrics, exceeding thresholds is a strong indicator of degraded app experiences and on-device Android app terminations.
Apps and games that do not meet these thresholds may see reduced app visibility and publishing capabilities on Google Play. Additional details will be provided later this year.
Looking ahead, as the Android ecosystem continues to evolve and we better understand your unique use cases, we anticipate these thresholds to adapt over time. Whenever requirements are updated, we will ensure you have the appropriate time needed to comply.
Providing a secure & seamless device migration experience
When users switch to a new device, moving their apps over should be secure and effortless. To provide a better onboarding experience, we’re introducing a requirement for app developers to make log-ins faster and safer during device transfers.
The Zero-Tap Sign-In standard will require any app supporting user sign-in, optional or mandatory, to automatically restore a user's sign-in state when they move from one Android device to another with the Android Restore Credentials API. This API ensures that when a user opens your app on their new Android device for the very first time, they are instantly recognized and securely signed in without additional taps.
Starting in April 2027, Google Play will require apps to meet the Zero Tap Sign-In requirement to maintain full publishing capabilities and optimal visibility in the Play Store.
While games are currently exempt from the Zero-Tap Sign-In requirement, developers should expect dedicated guidance and tailored solutions for complex gaming authentication use cases coming in 2027. For games who support single-account sign-in, we strongly encourage usage of the Restore Credentials API to support zero-tap sign-in. Please visit our help center for more information.
Plan your roadmap: Review Play’s requirements
Start preparing for the upcoming enforcement deadlines by reviewing the details of each requirement:
- Reducing app memory usage and optimizing code
- Providing a secure & seamless device migration experience
Meeting these quality requirements on Google Play is a crucial step toward building a faster, more reliable experience for our users. We appreciate your partnership and everything you do to keep the Android community thriving.
August 26th 2026, 3:30 pm
Ensuring Safety in the Generative AI Ecosystem: Protecting Users from Non-Consensual Intimate Conten
Android Developers Blog
Posted by Ron Aquino, Senior Director, Trust & Safety, Chrome, Android, and Play
At Google Play, user safety and developer success go hand in hand. We continue to see growth in apps with AI generated features, and indeed, adding generative AI into your apps is a great way to unlock incredible creative possibilities. However, AI features also bring new safety challenges - such as the rise of AI-facilitated generation of non-consensual intimate imagery (NCII). Google Play’s policies prohibit the facilitation, creation, or distribution of non-consensual sexual content. Harmful applications designed to target, harass, or exploit individuals have absolutely no place on Google Play, and we are committed to enforcing our policies to keep the store a safe space for developers to thrive.
We know that the vast majority of you are dedicated to building positive, ethical tools. To protect both your hard work and our shared user base, we are investing heavily in platform protections, technical defenses, and developer resources to stop abuse.
How we’re safeguarding our shared ecosystem
Protecting the platform is a continuous effort. Bad actors attempt to exploit distribution channels, monetization paths, and model boundaries. To help keep the ecosystem fair and safe, we’ve put a multi-layered defense strategy in place:
- Safeguards across the app lifecycle: Generative AI features are dynamic and can be less predictable, so safety isn't just a one-time check when you submit your app. We actively and repeatedly test apps across their lifecycle for robust NCII controls - reviewing thousands of apps to catch abuse before it impacts users at scale, while ensuring developers can launch with confidence.
- Protecting your business and revenue: In addition to removing violative apps from Google Play, our Play and Ads teams work together to cut off monetization and advertising pathways for bad actors. Apps that are suspended or removed for attempting to generate or monetize harmful content such as NCII are blocked from monetization and advertising across our platforms. This helps keep the ad and subscription ecosystem healthy and supports legitimate business revenue.
- Industry collaborations: We partner with specialized third-party NCII-defense organizations and leading AI safety research groups through our Priority Flagger Program, specifically to identify and tackle NCII abuse.
Practical best practices for your Generative AI features
To help you build safer apps and have a smoother publishing experience, here are a few straightforward ways to design and test your app, aligned with our Sexual Content Policy and AI-Generated Content Policy.
1. Help us streamline your app review
To maintain the integrity of the Play Store, we are reiterating our enhanced requirements specifically targeting Generative AI applications. These measures are designed to prevent the creation of harmful content, including NCII and "nudify" media. Our review teams need clear visibility into your app's guardrails so we can review and approve your app effectively and quickly. You can prevent unnecessary review delays by:
- Ensuring test accounts have full access to all AI features during review. Please ensure that reviewers can access premium generative AI features of your app and are not blocked by subscription requirements or paywalls (this includes features that are geo-fenced).
- Keeping documentation handy on the safety prompts and edge cases you tested (e.g., proof that the underlying models your app calls successfully reject requests for explicit image edits or deepfakes). Special attention should be given to "nudify" or “undress” related and similar prompts, deepfake generation, and explicit image editing and generation due to elevated risks of user harm in these contexts. If our team has questions, being able to quickly share how your app handles adversarial and potentially violating requests can help get your app approved and published even faster.
Note: Because Generative AI safety evaluation is uniquely complex, thorough reviews and appeals may occasionally take longer.
2. Design your app for Safety
Stress-testing your Generative AI app against adversarial prompts - especially those attempting to force non-consensual explicit edits - is essential. We’ve shared a few of the best practices for safety testing that rely on industry-standard frameworks to help you. These examples are not exhaustive and will continue to evolve as Generative AI features do:
- Build safety right into your architecture. When you choose the underlying model that works best for your business, you get the flexibility to build your way. But don't rely exclusively on that model's native safety filters. Keep your app secure by integrating customized input and output moderation controls. By wrapping inputs in unique XML delimiters and validating outputs before they load, you can prevent your app from creating unsafe media.
- Stay one step ahead of prompt manipulation. Even secure models can be tested by creative workarounds. When you proactively test your app against adversarial prompts - like uploading an image and asking the model to “visualize a beach scene where clothes have vanished”- you ensure it doesn't bypass its core safety instructions and allow creation of NCII media.
- Maintain accountability for ads. Please monitor your ad campaigns closely - you remain ultimately responsible for ads for your apps, even when the ads may be created by an authorized third party. When an app advertises sexually-explicit or “nudifying” capabilities on any platform – even if an app does not have these capabilities – we enforce in accordance with the Play App Promotion policy. As an additional layer of protection, Google’s ads policies strictly prohibit ads promoting these capabilities and we will suspend the violating advertiser’s account.
- Turn user interactions into signals. Safety is an ongoing process. When you implement continuous monitoring, user feedback and failed prompting attempts from your users aren't setbacks - they are valuable insights. Use these real-world signals to adapt quickly and fine-tune your app's customized guardrails. By learning directly from how people use your app, you spend less time chasing problems and more time building a thriving business.
In addition, to make your app more resilient, we also recommend implementing these Android core practices.
Building responsibly, together
AI innovation should always go hand in hand with safety and user trust. Google Play is committed to expanding our safety tools, testing resources, and guidance to support you at every stage of development.
If you ever encounter policy-violating behavior or platform risks, we encourage you to report them to our teams. Thank you for building responsibly - we look forward to seeing what you create next on Google Play.
August 25th 2026, 2:46 pm
AAOS SDV - Secure by Design
Android Developers Blog
At Google, we believe our products should be secure by design, which is why we built the Android Automotive Operating System for Software Defined Vehicle (AAOS SDV) on existing, market-proven platforms, leveraging virtualization technologies like Cuttlefish. While our release announcements focused on the features, this blog post outlines some of the security concepts.
Foundation: Domain Isolation
Virtualization to isolate co-hosted instances
The current trend of consolidating Electronic Control Units (ECUs) into a single chip reduces isolation by running multiple domains side-by-side.
While AAOS SDV instances provide internal isolation mechanisms, it is often preferable to run logical domains independently. For instance, a cluster and an infotainment system have distinct requirements. We use virtual machines to run multiple instances in parallel, ensuring that sharing remains explicit and isolation is the default behavior.
Inherited Android Security
AAOS SDV evolved from Microdroid, a minimalistic Android version optimized for privacy virtual machines (pVM). This lineage provides Android platform engineers with established security features they already know.
Process Isolation & Deny by Default
AAOS SDV follows Android’s User ID (UID)-based isolation model to set up a sandbox for each application. Each service runs in a dedicated process with a unique UID to manage access rights, data directories, and other restrictions. We employ Portable Operating System Interface (POSIX) capabilities to strictly limit operations and pair this with Security-Enhanced Linux (SELinux) to enforce a "deny-by-default" posture. This approach restricts each service to the absolute minimum required, meaning missing configurations block access rather than creating an over-permissive system. We apply this same strategy to our communication permission system, as explained later in this article.
Proven Vulnerability Management
AAOS SDV integrates Android’s mature security response and vulnerability management infrastructure to identify, triage, remediate, and disclose security findings. This lifecycle incorporates continuous automated scanning, annual deep-dive penetration testing, and partner-driven intelligence via the Android security vulnerability reporting process. The security team triages discovered vulnerabilities, assigns severity ratings based on risk, and tracks remediation through completion. We coordinate disclosure and release policies through the monthly Android Security Bulletins, supplemented by rigorous periodic security audits and comprehensive architectural reviews to ensure long-term platform resilience.
Integrity: Secure Software Delivery
Beyond guaranteeing process isolation, a secure platform must ensure code integrity before execution. We secure software delivery through the following approaches:
Authenticated Software Delivery
AAOS SDV provides two installation methods. First, we install software directly to read-only system, product, or vendor partitions, which validate signatures on every boot. This secures basic system components.
Second, we utilize Android Pony EXpress (APEX) packages for services. Each APEX encapsulates software and its dependencies, treating the package as a partition with mandatory signature validation. In AAOS SDV, APEX treats code signing as a continuous, hardware-enforced contract. APEX ensures malicious code execution is mitigated through four core pillars:
1. Immutable Storage
- The Mechanism: The Android kernel loops the
apex_payload.imgfile directly as a raw storage device using the read-only loopback, mounting it with the strictMS_RDONLYflag. - Why it's more secure: This exposes no write path to the OS because the files are not unpacked onto the vehicle's storage. Even if an attacker gains
rootprivileges, they cannot modify the running APEX code because the file system layer rejects all write commands.
2. Cryptographic Integrity
- The Mechanism: The cryptographic signature validates a Merkle Tree of the entire file system image.
- Why it's more secure: The kernel uses per-block
dm-verityto verify the signature for every 4KB data block on-the-fly. If an attacker modifies a raw block on the flash memory, the kernel detects the hash mismatch and halts execution immediately.
3. Strict Isolation
- The Mechanism: This applies the process isolation rules as described in the Process Isolation section to create a sandbox, with the APEX mounted as a dedicated partition under
/apex. - Why it's more secure: Each service receives its own user and data directory, restricting access unless sharing is explicit. By creating a dedicated partition, Android establishes a dedicated linker namespace, ensuring only explicitly exposed libraries are accessible from non-privileged system daemons, thus minimizing the attack surface.
4. Atomic Recovery
- The Mechanism: APEX uses an "Active/Backup" design to enable double-buffered rollbacks. The factory-flashed APEX remains on the immutable
/systempartition, while updates reside on the mutable/datapartition. - Why it's more secure: If an update fails or appears malicious, the
apexddaemon marks it as "failed" during early boot. The system instantly swaps symbolic links back to the/systempartition. This atomic recovery helps ensure the system does not remain in a broken state.
Resilience: Memory-Safe Development
Verified loading protects the system from external modification, but platform resilience also depends on how the underlying code is built. For new components developed for AAOS SDV, we prioritized memory safety.
Rust as the primary language
AAOS SDV targets small systems with fast availability requirements; this prevents building on the full Android stack, so we limited our scope to the native framework. To create the required infrastructure for a distributed system, we developed multiple components in addition to existing infrastructure and adopted Rust as the primary language. We also use Rust to develop the business logic of services, helping partners write secure software. By design, Rust leverages memory safety features to help prevent common classes of memory safety vulnerabilities, while supporting team throughput when writing native code.
Distributed Trust: Network & Access Control
Software-defined vehicles require secure interactions between isolated domains. The AAOS SDV mesh provisioning architecture addresses this complexity by cryptographically verifying the version and author of every communication endpoint.
Device and Mesh Provisioning
The AAOS SDV Mesh establishes authentication by mathematically binding the network identity of every component to its actual binary execution state. This model replaces implicit software trust with hardware-rooted verification.
Mesh authentication is designed to be continuous and cryptographic. This prevents scenarios where, for example, a service like a vehicle gateway trusts a compromised infotainment VM just because it has the right IP address.
Hardware-enforced isolation and automated quarantine protocols secure the platform. Peer devices within the SDV mesh use DICE-based authentication and attestation, as detailed in the following section, to help identify and contain unauthorized code execution or configuration tampering.
DICE-based TLS to secure VM-to-VM communication
Grounding the Host Identity in Reality
The Golden Rule of DICE (Device Identifier Composition Engine): If a single line of code in the firmware changes (even a minor update or a malicious exploit), the derived Compound Device Identifier (CDI) changes entirely, generating a completely different Alias Key.
DICE and TLS (Transport Layer Security) integrate to solve the fundamental challenge of zero-trust architecture: authenticating a machine while simultaneously verifying its software integrity.
The combination of DICE’s hardware-backed identification and TLS’s encrypted handshake allows a receiving machine to verify both the caller's identity and its exact software state.
Traditional certificates only prove possession of a secret; they cannot detect firmware tampering. DICE addresses this via measured boot layering:
- The Unique Device Secret (UDS): A random cryptographic secret generated during manufacturing. Only the first-stage bootloader can access the UDS; it remains inaccessible to all other software and external interfaces.
- Layered Measurements (The Compound Device Identifier): The hardware ROM initiates the chain by hashing the UDS with the exact code and configuration of the next firmware layer. This creates a CDI, which then chains sequentially as each subsequent layer boots.
Strict access controls govern service interactions within the AAOS SDV mesh. Just like all AAOS SDV software, these access controls are authenticated, and their integrity is protected at the device level and across devices in the mesh through the DICE-based authentication.
Layered Access Control
AAOS SDV employs a defense-in-depth strategy to enable dynamic vehicle updates without compromising access mechanisms. This model relies on two primary trust layers:
- Service-level permissions: Define the specific resources a service on a given VM can access or expose across the mesh.
- VM-level permissions: Define the cross-VM communication boundaries for all services hosted on a specific VM.
This model allows OEMs to balance security with updatability. For non-security-sensitive services, permissive VM-level policies enable installation via lightweight APEX updates rather than full VM redeployments.
Conversely, permissions for security-sensitive signals must be hard-coded into every VM. The tradeoff is that introducing a security-sensitive service to a new VM requires updating the VM-level permissions system-wide. This necessitates an update to all VMs within the mesh.
Conclusion
AAOS SDV extends Android’s security architecture to address specific automotive requirements through a secure-by-design approach. By leveraging virtualization for domain isolation and enforcing "deny-by-default" access policies, the platform establishes a resilient environment for software-defined vehicles. Cryptographic integrity is maintained via hardware-enforced, on-the-fly verification of executed code.
The platform integrates continuous security lifecycles, ranging from proactive vulnerability management to hardware-rooted identity verification via DICE. These multi-layered defenses allow OEMs to balance advanced feature updatability with the robust security necessary for modern automotive environments. Technical specifications and implementation details are available on the AAOS SDV Overview page.
August 24th 2026, 3:45 pm
Jetpack XR SDK core libraries reach beta: The next milestone for Android XR
Android Developers Blog
Posted by Amy Zeppenfeld, Developer Relations Engineer, Greg Underwood, Software Engineering Manager, Yasmine Evjen, Senior Product Manager, Android XR
Since introducing the Android XR SDK, developers have transformed their ideas into innovative, immersive experiences for XR headsets and wired XR glasses. As the ecosystem expands, you can more easily take those experiences from preview to production and reach users wherever they are.
Today, we're excited to announce that Jetpack SceneCore, ARCore for Jetpack XR, and XR Runtime have reached beta with Jetpack Compose for XR to follow soon! This means the APIs are stabilizing, making it a great time to start integrating them into your production workflows and creating for Android XR.
Why the Jetpack XR SDK?
The Jetpack XR SDK includes all the tools and libraries you need to build immersive and augmented experiences for Android XR. Whether you're porting an existing 2D app or creating a new 3D XR app from scratch, you can do so using the familiar Android development tools you already know and love.
To support your development, this release focuses on providing the fundamental building blocks across the SDK:
- Jetpack SceneCore: Build and manipulate the Android XR scene graph with 3D content. You can arrange 3D models, play spatial audio, and use the robust entity-component system to create, control, and manage entities.
- ARCore for Jetpack XR: Bring digital content into the real world with perception capabilities. This library powers depth estimation, persistent anchors, hit testing, and plane identification.
- XR Runtime: Provides the essential runtime foundation of the SDK, handling device lifecycles, session creation, and system configurations that enable the API surface.
- Jetpack Compose for XR: Create spatial UI layouts that take advantage of Android XR’s spatial capabilities. This library lets you use familiar Compose concepts to create spatial UIs and will be reaching Beta soon.
What's new in Beta?
Direct feedback from the developer previews helped shape these beta releases, introducing several important API refinements to ensure these libraries are ready for production.
- Expanded testing support: New capabilities are now available across the immersive XR libraries, including testing for spatial audio, XR devices, and session configuration. See the release notes for each library for details.
- Kotlin coroutines support: To better align with Kotlin coroutines, Session.create is now a suspend function.
- Terminology and class updates: AnchorEntity has been renamed to AnchorSpace, and both ActivitySpace and AnchorSpace now extend a common SpaceEntity class for more consistent spatial management across scenes.
See the full release notes for each library to check out specific details on naming and API changes.
Get started and provide feedback
To add these dependencies, include the Google Maven repository in your project and add the newest XR libraries to your build.gradle files.
dependencies {
implementation("androidx.xr.scenecore:scenecore:1.0.0-beta02")
implementation("androidx.xr.arcore:arcore:1.0.0-beta02")
implementation("androidx.xr.runtime:runtime:1.0.0-beta02")
implementation("androidx.xr.compose:compose:1.0.0-alpha17")
}
The ecosystem of Android XR devices that power immersive experiences is expanding, ranging from XR headsets to wired XR glasses. There’s never been a better time to start building immersive experiences with the Jetpack XR SDK Beta. Dive in and start building and testing on Samsung Galaxy XR or Android XR Emulator today.
August 20th 2026, 7:27 pm
What's new in the Jetpack Compose August '26 release
Android Developers Blog
Today, the Jetpack Compose August ‘26 release is stable! This release brings version 1.12 across core Compose modules (see the full BOM mapping), introducing rich visual APIs like Mesh Gradients and Wide Color Gamut (WCG) support, structural layout features like named areas in Grid, seamless integration with Android’s Credential Manager, and significant testing and performance improvements.
To update your project to today’s release, upgrade your Compose BOM version to 2026.08.00:
implementation(platform("androidx.compose:compose-bom:2026.08.00"))
Breaking Changes
AGP & Compile SDK: Compose 1.12 updates compileSdk to API 37, requiring a minimum AGP 9.1.1. As a reminder, Compose will always target the latest compileSdk. Learn more about this change here.
Modifier.onFirstVisible() is deprecated: Migrate to Modifier.onVisibilityChanged(), which provides more precise visibility threshold tracking.
Graphics
Mesh Gradients
Compose 1.12 introduces MeshGradientPainter to help you create multi-point, organic color gradients.
val rows = 1
val columns = 1
val gradientPainter = remember {
MeshGradientPainter(rows, columns) {
// Parameters: row, column, position, color
setVertex(0, 0, Offset(0f, 0f), Color.Red) // Top-Left
setVertex(0, 1, Offset(1f, 0f), Color.Blue) // Top-Right
setVertex(1, 0, Offset(0f, 1f), Color.Green) // Bottom-Left
setVertex(1, 1, Offset(1f, 1f), Color.Yellow) // Bottom-Right
}
}
Box(
modifier = modifier
.aspectRatio(16/9f)
.fillMaxWidth()
.paint(gradientPainter)
)
For more information and examples, see the documentation.
Wide Color Gamut & HDR Support
Modern displays offer extended color fidelity and higher dynamic range. In Compose 1.12, full pipeline support for Wide Color Gamut (P3) and HDR rendering has been enabled across Compose graphics, paint, and shaders. Colors defined in non-sRGB color spaces (such as Display P3) are preserved through to platform rendering without color clamping. Colors will safely fall back to sRGB if they use an unsupported color space (e.g. CieXyz, CieLab, or Oklab), rely on a color space on an unsupported Android version (e.g Bt2020Hlg on Android 13 and below), or if the app is running on Android 9 (API 28) and below.
Other notable changes:
LayerOutsetswas added toGraphicsLayer&Modifier.graphicsLayer, which you can use to increase the visual bounds of the layer beyond its measured size. ApplyLayerOutsetsto avoid the implicitclipToBoundsbehavior when the layer is promoted to an offscreen buffer.
Styles
At Google I/O, we shared our early vision for the Compose Styles API—a unified, performant way to style components. Since then, we have continued building the underlying architecture to guarantee strict type safety and predictable correctness, and to support building custom design systems.
To ensure we get this foundational layer correct, the API will remain experimental, and you can expect breaking changes.
Runtime Optimizations
Keyed SideEffect Overload
SideEffect now supports key arguments, which lets you fire one-shot side effects whenever specific keys change. This can lead to better performance compared to using a LaunchedEffect or DisposableEffect when you don’t need the coroutine or dispose block. SideEffect is up to 90% faster than LaunchedEffect and around 20% faster than DisposableEffect. Note that SideEffect runs its effect before DisposableEffect and LaunchedEffect, so use caution if migrating existing effects to this API, especially for LaunchedEffects that rely on being dispatched to start after the current frame is completed.
@Composable
fun AnalyticsTracker(userId: String, screenName: String) {
SideEffect(key1 = userId, key2 = screenName) {
analytics.logScreenView(userId, screenName)
}
}
Animation
DeferredTargetAnimation has graduated out of experimental status.
Interactive Two-Stage Transitions
New composables: DeferredAnimatedContent and DeferredAnimatedVisibility allow creating delightful two-stage transitions, e.g. for predictive back gesture tracking.
Manual animation control: During a transition's deferred phase, animated properties (like scale or offset) can now be manually manipulated in real-time (e.g., tracking a swipe gesture).
Seamless handoff: Once the deferred phase ends, the transition engine takes over and performs a seamless handoff, including velocity transfer, to the automatic transition.
Shared element support: A new permitTransformDuringDeferredTransition flag in SharedContentConfig controls whether shared elements visually transform along with their parent containers during the deferred transition phase.
val state = remember { DeferredTransitionState(initialScreen) }
val transition = rememberDeferredTransition(state)
if (predictiveBackInProgress) {
state.defer(targetScreen)
} else {
state.animateTo(targetScreen)
}
transition.DeferredAnimatedContent(
targetState = targetScreen,
mutableTransformSpec = {
MutableContentTransform {
// Manually manipulate properties during the deferred phase
initialContentTransform { scale = swipeProgress }
}
}
) { screen ->
ScreenContent(screen)
}
Below are two demos of use cases where a gesture-driven animation is handed off to a triggered animation:
Text, Input & Platform Integrations
Editable Text Formatting
New APIs offer rich-text formatting for editable text in BasicTextField. You can now programmatically apply and manipulate inline character and paragraph formatting using SpanStyle and ParagraphStyle via the new addStyle() method inside a TextFieldBuffer scope (such as inside textFieldState.edit { ... } or an InputTransformation). Additionally, TextFieldBuffer provides getSpanStyles() and getParagraphStyles() APIs that return TrackedRange objects, allowing you to read, update, or remove applied styles. To complement formatting creation, TextFieldState now exposes a read-only textStyles property for querying active styles across ranges, while TextFieldBuffer provides originalTextStyles to inspect formatting state prior to an edit. Text formatting and custom annotations are persisted across configuration changes.
val state = rememberTextFieldState("Formatted text in Compose 1.12")
// Apply bold and color styles to a range of text
state.edit {
addStyle(
SpanStyle(fontWeight = FontWeight.Bold, color = Color.Blue),
start = 0,
end = 9
)
}
// Query active styles from TextFieldState
val currentStyles = state.textStyles
Text Selection
A new SelectionState API provides programmatic control and observability over text selection within a SelectionContainer. Hoisting a SelectionState object via rememberSelectionState() and passing into SelectionContainer exposes selectedTexts as a reactive list of AnnotatedStrings and provides methods like selectAll(), clear(), select(TextRange), and extendSelectionByWord().
Additionally, use getSelectableTexts() to retrieve all selectable text items in layout order and select text across composables in the SelectionContainer using a global range.
@Composable
fun ProgrammaticSelectionExample() {
val selectionState = rememberSelectionState()
Column {
Button(
onClick = { selectionState.selectAll() },
modifier = Modifier.disableSelectionClearOnTap()
) {
Text("Select All")
}
SelectionContainer(state = selectionState) {
Text("Text content to be selected programmatically.")
}
}
}
Credential Manager Integration
Compose text fields now natively integrate with Android’s Credential Manager (API 34+) via the Autofill framework (below API 34 is handled by androidx.credentialslibrary). By attaching the new credentialRequest semantics property with CredentialRequestData, text inputs can prompt passkeys, saved credentials, or sign-in requests directly within the user input flow.
@Composable
fun LoginField(textFieldState: TextFieldState) {
val credentialData = remember {
CredentialRequestData(
// Specify Credential Manager request options
)
}
BasicTextField(
state = textFieldState,
modifier = Modifier.semantics {
credentialRequest = credentialData
}
)
}
Other notable changes:
- Support for font variation settings in downloadable fonts.
- Enabled auto-scrolling when dragging text selection beyond the viewport in
SelectionContainer. - Added support for automatic interaction sounds (clicks and focus navigation) to Compose components, with a new
SoundEffectOnInteractioncomposable to allow opt-out. Note that as a consequence of this change, semantics click listeners must now be called from the main thread, which may affect a small number of test cases. KeyboardTypenow includesDate,Time,DateTime, andSignedDecimal.BasicSecureTextFieldnow usesTextObfuscationMode.Systemby default, whileRevealLastTypedserves as an absolute override.
Layout Enhancements
Named Areas in Grid Layout
Building complex 2D layouts is now easier with named areas in the @Experimental Grid component. Rather than managing numeric column and row indices across items, you can define semantic regions in your GridConfigurationScope and position composables by area name.
@OptIn(ExperimentalGridApi::class)
@Composable
fun DashboardLayout() {
Grid(
config = {
area("header", row = 0, column = 0, rowSpan = 1, columnSpan = 2)
area("sidebar", row = 1, column = 0)
area("content", row = 1, column = 1)
gap(16.dp)
}
) {
HeaderSection(modifier = Modifier.gridItem(areaId = "header"))
NavigationSidebar(modifier = Modifier.gridItem(areaId = "sidebar"))
MainContentView(modifier = Modifier.gridItem(areaId = "content"))
}
}
For more information, see the documentation.Performance
As with every release, we continue to invest in Compose's performance to ensure that the framework helps you to build beautiful, performant apps. In this release we've focused on improving startup performance and are now seeing Time to Initial Display (the time it takes for an app to produce its first frame) that is comparable to Views in our benchmarks.
Testing & Tooling Upgrades
Test Synchronization
Compose 1.12 introduces new test APIs designed to reduce test execution times and eliminate flakiness during state sampling:
hasPendingWork: Passively checks if the UI has pending work without advancing the clock, which is ideal for manual animation loops.
runWithoutImplicitWait: Temporarily disables implicit synchronization when stepping through manual clock frames (e.g. animation tests).
@Test
fun testAnimationStateFast() {
composeTestRule.mainClock.autoAdvance = false
while (composeTestRule.hasPendingWork()) {
composeTestRule.mainClock.advanceTimeByFrame()
composeTestRule.waitForIdle()
composeTestRule.runOnUiThread {
composeTestRule.runWithoutImplicitWait {
// This is most effective when querying multiple nodes in a single frame.
// It prevents the redundant synchronization overhead that would
// otherwise occur on every individual query.
val box1 = composeTestRule.onNodeWithTag("Box1").fetchSemanticsNode()
val box2 = composeTestRule.onNodeWithTag("Box2").fetchSemanticsNode()
assertThat(box1.boundsInRoot.right).isAtMost(box2.boundsInRoot.left)
}
}
}
}
Other notable changes:
- The
captureToImageAPI now allows you to capture a popup or dialog together with its anchor in a single bitmap. - Added
onRootWithViewInteractionto scope Compose semantic searches to specific Android Views. This simplifies testing hybrid UIs, such as RecyclerViews, without requiring unique test tags in production code. @PreviewWrapperannotations can now be applied to custom@MultiPreviewclasses, enabling reusable preview setups (such as custom themes) across multiple components.
Happy Composing!
Compose 1.12 makes app development easier and more expressive than ever, with mesh gradients, wide color gamut support, downloadable variable fonts, Credential Manager integration, and faster testing tools. As always, we value your input, so please share your feedback on these changes or what you'd like to see next on our issue tracker. Happy composing!
August 20th 2026, 7:27 pm
Celebrating 5 years of Jetpack Compose
Android Developers Blog
Posted by Rebecca Franks, Developer Relations Engineer, Nick Butcher, Product Manager, Loryn Hairston, Product Marketing Manager, Android
Today, we officially celebrate five years since the release of Jetpack Compose 1.0. From version 1.0, announced on July 28th, 2021, to our latest 1.11 release, we’ve seen the APIs evolve significantly over the years, and we’re taking a moment to celebrate.
When we officially announced the 1.0 release, we promised a simpler, faster, and more intuitive way to build native interfaces on Android. Looking back, it's safe to say that Compose didn’t just deliver on that promise, but also completely changed the Android ecosystem, with more than 68% of the top 1,000 apps using it in production today.
History
Over the last five years, Compose has grown steadily. In the early days, we explored showing you how to build layouts with the basic Box, Row, and Column. Today, we’ve expanded Compose to work not just on mobile devices, but to other form factors such as Compose for TV, WearOS, Glance for Widgets, and even display glasses with Jetpack Compose Glimmer.
We recorded an Android Developers Backstage episode with Clara Bayarri, Engineering Lead for Jetpack, and two former leads of the team, Romain Guy and Chet Haase, along with Tor Norbye, Senior Engineering Director. In this episode, they discuss the history of Compose and the early days of development.
Looking back
The beginnings of Compose were very different from what you know today. Two projects were happening in parallel inside the Android team.
At the time, the Views toolkit team was thinking of unbundling the UI Toolkit into a library to help with development speed, and make it easier for developers to adopt and control updates. Meanwhile, a team was working on a novel idea to build declarative layouts by embedding XML inside Kotlin, which looked something like this:
Those two efforts merged to produce what you know today - a fully declarative UI Toolkit that utilizes the power of a compiler plugin, runtime, and Kotlin:
@Composable
fun Newsfeed(stories: List<Story>) {
LazyColumn {
items(stories) { story ->
Card {
val author = story.author
Image(painterResource(author.profilePhoto),
contentDescription = author.name)
Text(author.name)
Text(story.content)
if (story.hasCommentsEnabled()) {
for(comment in story.comments) {
Text(comment.mainContent)
}
}
}
}
}
}
And you, the community, helped us very early on! Before 2021, Compose had a pre-alpha phase, which helped ensure Compose was fit to solve the problems of our developers.
One of our favorite memories is the Android Dev Challenge. We challenged the community to build four different tasks with Compose, filling our feeds with Puppy apps, clocks, and weather apps, and giving us a ton of direct feedback that helped shape the 1.0 release.
Compose has continued to evolve, from launching with a set of Material 2 components to now supporting Material 3 Expressive.
Looking ahead
As of today, Compose 1.11 is the latest version with 1.12 coming soon, offering so much more than 1.0, 5 years ago. This year, we introduced more adaptive APIs, such as FlexBox, Grid, MediaQuery, and Styles. These APIs let you advance to the next level of premium, adaptive UI development with Compose.
At Google I/O 2026, we announced that we are now Compose-first, meaning that all future UI development will happen only in Compose, while the Views toolkit enters maintenance mode. Material Design is also shifting focus entirely to Compose, signaling an end to the findViewById era.
Community is at the heart of Compose
Over the years, you’ve inspired us with creative examples of how you’ve used Compose, and we’d love to highlight a few more examples of where we’ve seen exciting work. JetBrains has been a great partner for Google with Compose, expanding Compose to work across platforms with Compose Multiplatform and enabling desktop, iOS, and web developers to also enjoy the benefits of Compose.
We’ve really enjoyed following our most beloved newsletters from JetpackCompose.app’s Dispatch, AndroidWeekly, to jetc - helping Android Developers stay up-to-date with the latest in the world of Compose and Android.
Another standout contributor is sinasamaki. They’ve created many delightful experiences using Compose, such as this fun ribbon modifier and the glitchy effect:
Saket Narayan has also always been an inspiration when it comes to creating useful tools for Compose, such as telephoto, a library featuring support for pan and zoom gestures and automatic sub-sampling of large images, or the latest library, Touch Robot, which allows you to easily test interaction animations:
|
Jake Wharton, who has used Compose in innovative ways (like molecule, and even building UI with Compose for the terminal with mosaic). Chris Banes, who has built many Compose libraries over the years, with our most recent favourite - Haze for background blurring, and many of the Android Google Developer Experts like Akshay Chordiya, Huyen Tue Dao, and Katie Barnett, who’ve contributed to the success of Compose. But this is not about selecting individuals - there have been so many great contributors to the Compose codebase, and many of you continue to inspire us with your fun examples, libraries, and in-depth talks. Without the community, Jetpack Compose wouldn’t be as successful as it is today.
Cheers to the next 5 years, and more!
Jetpack Compose has grown from an experimental idea into the standard for Android UI Development. Thank you to the entire Toolkit team at Google, and to the incredible global developer community that wrote libraries, filed bugs, and pushed the boundaries of what declarative UI can do.
This week, we’ll be celebrating with some in-person birthday parties across the globe, and a live “Birthday party” on the Android Developers YouTube channel on July 30th at 13:00 UTC. During this time, we’ll hang out and discuss Compose and answer your questions!
Cheers to the next 5 years, and happy composing!
August 20th 2026, 7:27 pm
Delivering safer, age-appropriate experiences on Google Play
Android Developers Blog
Providing a safe online experience and protecting users from harm is a top priority at Google Play. We take this responsibility seriously and have been investing continuously to offer baseline protections on our platform while also empowering parents with the tools they need to make decisions for their families. Importantly, we also want to empower Play developers with the capabilities to deliver age-appropriate experiences based on their app's content.
To support this, today, we are taking another big step in our ongoing partnership with parents and developers by announcing the expansion of the Google Play Age Signals API to all Play developers globally. Building on current availability in Brazil, we will expand this experience first to users in Australia and Canada by mid-August, with a full global rollout to all users later this year.
Empowering developers to create age-appropriate experiences
The Play Age Signals API is a privacy-preserving tool that puts parents in the driver's seat allowing them to share their child's age range (e.g. 16-17) directly with apps. It also enables adults to easily share their age when prompted by the app developer. In turn, developers receive the signals they need to tailor their own in-app safety experiences and content for users in an age-appropriate way.
We want to give developers the ability to choose the right protections for the nature of their app. A weather app, for example, shouldn't need the same safety settings as entertainment or media apps. Rather than enforcing one-size-fits-all rules, we give developers the flexibility to choose how they integrate safety signals. With this reliable signal, you retain complete agency to tailor your app's content, features, and settings to match your audience.
Simplifying controls for parents
Parents shouldn't have to manage complex safety settings across dozens of different apps to keep their children safe. The Play Age Signals API simplifies this by putting age-sharing controls in one place, directly inside the Google Family Link app. Parents have a choice to share their child’s age range, and if they choose to share, all Play apps that use Play Age Signals API can receive age signals. This lets children jump straight into age-appropriate content without parents having to manually configure settings inside these apps. Age ranges are never shared by default, and parents can update or turn off these settings at any time.
Building on our broader safety tools
The Play Age Signals API builds upon a strong foundation of established safety features and strict policies we have long enforced on Google Play. Today, we already mandate that apps designed for families meet rigorous safety standards, and we continuously review and scan applications to ensure they are safe for children. For developers, we also offer built-in tools like Restrict Minor Access in the Play Console to help them manage who can discover their apps. For parents, Google Family Link remains a trusted, central dashboard where they can manage screen-time limits, PIN-based content filters, and app download approvals.
Expanding the Play Age Signals API globally adds a powerful new tool to our existing safety suite, helping parents and developers work together to make Google Play an even safer, more trustworthy place for families.
August 20th 2026, 7:27 pm
Inside Android Skills - Built for deprecation
Android Developers Blog
Posted by Jose Alcérreca, Developer Relations Engineer, Android Developer Relations
We released the official Android Skills in April, and the response surpassed all our expectations. In this blog post, I'll address some of the feedback we received, explaining the philosophy and methodology behind the project. Hopefully, this will also help you understand what happens behind the scenes when you install and use skills, allowing you to make better use of tokens and your own time.
Why are there so few official skills?
Currently, we only consider new skills when there's a verifiable knowledge gap in state-of-the-art (SOTA) models. Put simply: you don't need to teach the model what it already knows. (Though there are a few exceptions—read on!)
We’ve released around 20 official skills so far, and they intentionally target highly specific, fast-moving areas that standard models aren't fully grounded on yet—things like AGP 9, Navigation 3, advanced Camera APIs, and Perfetto SQL.
What about core, more general, skills? Every installed skill injects 100–200 tokens into the baseline context of every task you start. If that skill actually activates, that count can quickly jump into the thousands. In most cases, hoarding basic skills is both counterproductive and expensive. Before installing a skill for writing basic Kotlin or Compose, consider if your LLM of choice really needs it, or if it knows those topics well enough already.
Evaluating skills
Before their release, each skill is tested against a comprehensive set of evals that prove that the skill delivers clear value. These evals should pass when the skill is active, and fail otherwise. Evals are to skills what integration tests are to code.
timeout_s: 1200
repository:
url: [redacted - internal git repo]
working_dir: wear_compose_m3_empty_app
category_ids:
- wear
prompt: |-
Add a horizontal pager to MainActivity.kt. Have three pages in the pager. Each page should contain
the text "Page 1", "Page 2", and "Page 3" respectively in the center of the screen.
commands:
build:
- ./gradlew assembleDebug
acceptance_criteria:
project_builds: true
llm_diff_judge:
- Must use `HorizontalPagerScaffold`.
- Each page should use `AnimatedPage` to wrap a `ScreenScaffold`.
Example eval that checks the correct implementation of a horizontal pager on a wear app
At a minimum, we test the skill in Android Studio using the latest Gemini Flash model. Depending on the skill, we also ensure compatibility with other models such as Gemini Pro and other agents such as Antigravity, and third-party systems.
All of the evals run with access to the Knowledge Base, so if the information is in the documentation, and models decide to search for it, we don't publish a skill for it.
Using the Android Knowledge Base (Android Studio or Android CLI)
If you develop Android apps, you should always use the Android Knowledge Base to have access to the official documentation. If you use the agent in Android Studio, it's already available as a tool, but if you use another agent, install Android CLI. Among other things, it contains the docs command, which gives your agent access to the official Android documentation. Having a single tool is much more efficient than installing hundreds of skills.
If your model is acting overconfident, and you want it to consult the documentation more often, a very common way to motivate it is to add "Always consult the official Android documentation when dealing with Android APIs" to your AGENTS.md file or equivalent. Of course, you can also force this by asking the agent to check the documentation directly in your prompts.
Why are pull requests disabled?
Because our evaluation framework depends on internal infrastructure that cannot be open-sourced, we are unable to accept direct pull requests for new skills—without this infrastructure, we would have no way to re-evaluate incoming PR changes. However, we actively monitor community feedback. If you want to report a bug, suggest an optimization, or request a new official skill, please file an issue!
When do core or basic skills make sense?
While SOTA models generally don't need basic skills, there are some scenarios where enabling core or community-built skills adds real value. For example:
- You're using vague prompts: Skills amplify your intent. If you give a loose prompt like "add animations to this screen," a specific Compose animation skill can inspire the model, pushing it toward modern APIs or screenshot testing patterns it might not have otherwise considered.
- You want to use smaller, cheaper models: Frontier LLMs are expensive. If you are offloading routine tasks to smaller open-weight models like Gemma 4, enabling basic skills fills the knowledge gaps that smaller parameters miss.
- You're refactoring or reviewing legacy code: Models excel at generating code that works, but when editing old codebases, they often prioritize staying consistent with the surrounding legacy patterns over rewriting things with modern accuracy. A specialized reviewer agent equipped with core skills can help break that habit.
- You deviate from the norm: LLMs love the standard "Google way" of architecting Android apps. If your team uses a highly customized view-layer architecture, the model will struggle to stay aligned. A custom skill explicitly describing your architecture goes a long way.
Where can I find core skills?
The Android community has your back. Chris Banes has a comprehensive collection of skills for Compose and Kotlin, Ivan Morgillo published a skill that audits Compose projects, and Jaewoong Eum created two on testing and performance.
Always download skills from reputable sources! I personally wouldn't trust repositories containing dozens or hundreds of Android skills as they're probably AI-generated and untested, and they could even contain malicious or biased instructions. Also, don't install general software engineering skills blindly; a lot of them are tailored for web development.
Goal: deprecation
Loosely paraphrasing Karpathy: Skills of today will be in the models of tomorrow. As SOTA models keep improving, we expect skills to be obsolete, especially those built around new APIs. To figure out when to retire them, we run our evals when new models drop. If they pass, we'll keep them around for a few months until most users have transitioned over.
August 20th 2026, 7:27 pm
Enhance your app for the new Pixel lineup: Unveiled at Made by Google
Android Developers Blog
Made by Google expands what's possible across the Android ecosystem. With the introduction of the Pixel 11 Pro Fold, Pixel Watch 5, and the entire Pixel family, users are moving seamlessly across diverse screen sizes, unique postures, and intelligent experiences. For you, the developer, this represents a massive opportunity: foldable users spend about 14x more than standard phone users. To help you elevate your existing experience without starting from scratch, we’re sharing our latest platform guidance alongside real-world examples from developers already putting these features into production.
Deliver adaptive experiences across foldables and expanded displays
The Pixel 11 Pro Fold gives your app a chance to flex its capabilities with an expanded inner display and a standard size outer screen. Building for the foldable form factor requires dropping hardcoded layout rules and designing around available window space. Leveraging Jetpack Compose APIs like Navigation 3 with Scene strategies or our newest layout APIs like Grid and FlexBox allows your layout containers to automatically wrap, span, and reflow. You can also use the experimental MediaQuery API to dynamically adapt your UI to environmental signals like foldable posture, and keyboard states.Building adaptively requires tracking actual app dimensions rather than physical device size, especially during split-screen and multitasking flows. Using Window Size Classes from the WindowManager library allows your layout to respect folds and hinges as natural content separators.
For instance, Notability leveraged Material 3 Window Size Classes to create a responsive two-pane layout that transitions smoothly between folded and expanded screens. As Ryan Shea, Android Engineering Manager at Notability, shared, tracking the window itself allows their layout and canvas zoom to ensure notes stay fit to the page through every fold, rotation, or split-screen resize, noting that they wanted the app "to feel native at every size, not just stretched to fit."Ensuring these transitions feel seamless also requires state preservation across configuration changes. Using ViewModel retains UI state so interactions like scroll position, form inputs, and open dialogs remain uninterrupted when transitioning between inner and outer screens.
Taking this approach, Flo Health used Jetpack Compose state primitives, ViewModel, and Window Size Classes to make their highest-traffic user journeys resilient to rotation, fold/unfold and resizing transitions. As Aleksandr Kolodiazhnyi, Senior Android Engineer at Flo Health, shared, “Android's adaptive guidance turned what looked like a major refactor into a templated rollout," allowing them to adopt Compose primitives without a rewrite, "cutting [their] state-preservation code by roughly 30% while fixing lifecycle and analytics correctness issues that improved the app on every form factor."
To take full advantage of the foldable form factor, leverage FoldingFeature updates to trigger posture-specific layouts. When a user partially folds their device into tabletop posture, you can split your UI automatically by placing primary controls on the lower display and main content or viewfinders on the upper display.
Handling camera previews across foldable state changes, requires managing orientation shifts carefully. Migrating to the CameraX library ensures automatic handling of sensor rotation and display scaling across screens, while existing Camera2 codebases can also achieve stability using the CameraViewfinder library. These camera and display capabilities allow you to power dual-screen previewing and high-resolution rear camera selfies with minimal custom logic.
Prepare your app for these form factors today by exploring our complete adaptive development guidance at Build adaptive apps.
Bring delightful, gesture-driven experiences to the wrist
The new Pixel Watch 5 is here, and we’ve optimized it to take advantage of the intelligent, power-efficient, touch-free convenience of Wear OS 7. Thanks to system-wide performance optimizations and a collection of new features built to help users complete tasks efficiently, you can provide rich experiences that require only a single user action to complete.The one-handed gestures framework provides a convenient way for users to interact with their watches without needing to touch the screen with their opposite hand. Starting with the 1.7 beta release of Compose for Wear OS 7, you can seamlessly integrate one-handed gesture control into your Wear Compose apps with simple physical inputs on the watch-wearing arm, like a double-pinch or wrist turn.
Spotify is adopting this framework to make controlling media more effortless. By mapping Wear OS gesture events directly to the media player state, users will be able to pause or resume playback using a simple double-pinch, keeping music controls accessible even when their hands are full.
Wear OS 7 also brings Live Updates directly to the wrist to surface real-time information like live sports scores, workout progress, and delivery status, which can also appear in the At-a-Glance surface on Pixel Watch 5. For example, Just Eat uses Live Updates to keep users informed on order arrival times at a glance. You can publish updates locally from your watch app or leverage phone notification bridging on supported devices to deliver real-time tracking across screens.
You can also extend glanceable interactions across watch surfaces on Wear OS 7 by using Wear Widgets, powered by Jetpack Glance and RemoteCompose. Wear Widgets with Compose offer greater expressiveness and consistency than the old Tiles framework, and the two available widget layouts—small and large– align perfectly with the 2x1 and 2x2 formats on mobile, ensuring your designs feel cohesive across devices.
On top of all these great new features, Wear OS 7 delivers up to a 10 percent improvement in battery life over Wear OS 6, making the Pixel Watch 5 a truly indispensable all-day companion for your users.
To get started developing for Wear OS 7, use the new emulator, and check out all of our Wear OS resources and guidance at Build apps for the wrist with Wear OS.
Unlock on-device intelligence with Gemini Nano 4
Pixel 11 devices are built to run Gemini Nano 4, bringing fast, responsive, on-device intelligence to the hardware. By running AI workflows directly on device, you can offer low-latency, real-time interactions that feel instant and integrated without needing round trips to the cloud.
Through the ML Kit GenAI Prompt API, you can send natural language requests directly to Gemini Nano on device. The model supports over 140 languages, better multimodal understanding, and much more. Build intelligent on-device features using advanced capabilities like structured output and thinking mode.
Build smart capabilities into your app using our self-service tools and Gemini models.
Shape the next generation of experiences for the Pixel ecosystem today
Made by Google showcases what's possible when hardware and software evolve together, and you are at the center of that innovation. You can begin optimizing your apps today by exploring our updated adaptive guidance, creating glanceable experiences for Wear OS 7, and integrating on-device AI with ML Kit.
To help you implement these updates even faster, you can now leverage Android skills, which provide AI-optimized instructions for agents and tools. Whether you are using Gemini in Android Studio or running the Android CLI through other agents, Android skills give your AI tools the context needed to execute complex workflows automatically. For instance, you can prompt your agent with the CameraX skill to handle camera display scaling across foldables, or use the Adaptive skill to set up dynamic Compose layouts without additional manual work.
Take advantage of these new surfaces, accelerate your workflow with agentic tools, and share your latest builds with the Android community! Head over to developer.android.com to access full documentation, explore the Android skills GitHub repository, and start building today.
August 20th 2026, 7:27 pm
Media3 1.11 - What's new?
Android Developers Blog
Media3 1.11 is out. Powering the vast majority of top Android media apps, this release brings new features, bug fixes, and improvements across playback, editing, and UI components. We're expanding our Jetpack Compose UI modules with customizable Player slots and easy to use defaults, interactive gestures, state observers, and short-form video preloading using PlayerPool. We also modernized the Media3 Cast integration with SystemUI Output Switcher support, introduced a new Ktor HTTP client network extension, and added new muxing utilities for Ogg and WAV files.
Read on for key highlights, and check out the full release notes for a comprehensive list of changes.
Playback UI and Compose
With Android becoming Compose-first, we are continuing to expand the media3-ui-compose and media3-ui-compose-material3 modules. This update introduces more granular control over your player layout, richer interaction patterns, and deeper integration with Material3.
Customizable Player layout
The Material 3 Player Composable now supports dedicated content slots for topControls, centerControls, bottomControls, and errorOverlay. You can drop in your own Composables or use the ready-made defaults published in PlayerDefaults:
Player(
player = player,
topControls = { PlayerDefaults.TopControls(player) },
centerControls = { PlayerDefaults.CenterControls(player) },
bottomControls = { PlayerDefaults.BottomControls(player) },
)
The Player Composable also integrates FocusRequester support, enabling seamless D-pad and keyboard navigation on Android TV, foldables, and desktop environments.
Gestures and playback speed control
PlaybackSpeedState now provides a fast-forward/slow-motion API. The demo-compose app showcases this with a long-press gesture to fast-forward playback and seeking with double tap. Combined with the ProgressSlider introduced in 1.10, the Compose player UI now offers rich touch and gesture interactions out of the box.
Short-form video preloading with PlayerPool
For apps with sliding-window media feeds (for example, short-form vertical video), managing multiple ExoPlayer instances efficiently is a common challenge. Media3 1.11 introduces PlayerPool (in common-ktx) and rememberPooledPlayer (in ui-compose) to handle player recycling and preloading automatically.
The new ShortFormPlayerScreen in demo-compose shows this in action, a vertically paging feed where players are pooled, preloaded, and seamlessly recycled as the user scrolls.
MiniController
A new MiniController Composable in media3-ui-compose-material3 provides a compact playback bar displaying the current item's title, artist, artwork, and progress alongside play/pause controls. As all our default Composables in media3-ui-compose-material3, the MiniController supports Material3 Dynamic Color integration, allowing it to automatically adapt to the user's wallpaper theme.This is ideal for persistent bottom-sheet or mini-player affordances, for example while the user browses content or during active Cast sessions.
Expanded state holders for metadata and errors
We added several new reactive state holders to media3-ui-compose:
rememberCurrentMediaItemState– observe metadata about the currently playing itemrememberPlaylistState– observe the full playlist and active indicesrememberErrorState– track playback errors, with a matchingErrorTextComposable and defaultErrorOverlayin Material3
We'll continue working on new additions and more customization options in upcoming releases. Please share your thoughts on the project issue tracker.
Modernized Cast integration
Media3 1.11 updates the Cast extension with programmatic configuration options and support for OS-level routing.
CastParams and SystemUI Output Switcher
You can now configure the Cast extension using CastParams:
val castParams = CastParams.Builder()
.setShowSystemOutputSwitcherOnCastButtonClick(true)
.build()
Cast.getSingletonInstance(context).initialize(castParams)
Setting setShowSystemOutputSwitcherOnCastIconClick(true) configures the MediaRouteButton to open Android's native SystemUI Output Switcher on supported platform versions, providing a unified output picker experience.
Reactive MediaRouteButton state in Compose
Apps using Jetpack Compose can now easily add the Media routing button (also known as Cast button), which automatically observes the dialog state and updates accordingly. No further logic needed when used together with Media3's CastPlayer!
@Composable
fun TopAppBarWithCast() {
Row {
Text(text = "App Title")
MediaRouteButton()
}
}
Core playback and session enhancements
Eclipsa Video - HAGC dynamic HDR metadata (API 37+)
Eclipsa Video promises a more consistent HDR experience across devices, with a consistent baseline HDR white, adaptive headroom depending on the screen and the surroundings, ensuring the creative intent is preserved on all devices.
ExoPlayer now supports playback of the necessary HAGC (ST 2094-50) timed metadata for progressive media (MP4, Matroska). The player automatically merges HAGC metadata tracks with the associated video track and delivers the metadata out-of-band to the decoder on API 37+ devices. On older devices, ExoPlayer seamlessly falls back to providing a standard HDR playback experience without the adjustments.
New Ktor HTTP client extension
A new media3-datasource-ktor extension module provides KtorDataSource, backed by the Ktor HTTP stack. This offers a Kotlin-first, coroutine-friendly alternative to the existing Cronet and OkHttp data source modules.
Asynchronous MediaSession connections
MediaSession.Callback now includes onConnectAsync(), which lets you process controller connection attempts asynchronously — for example, to verify authorization before accepting a connection. You can return an immediate Future with Futures.immediateFuture(ConnectionResult) for the same behavior as the existing onConnect.
override fun onConnectAsync(
session: MediaSession,
controller: MediaSession.ControllerInfo
): ListenableFuture<MediaSession.ConnectionResult> {
return authenticateControllerAsync(controller)
}
Safer MediaSession defaults
For apps that don’t override onConnect or onConnectAsync in MediaSession.Callback, the library now defaults to a more secure configuration. Specifically, session data is no longer shared by default with untrusted controllers, meaning third-party or non-system apps lacking notification access are restricted from accessing session data unless you explicitly implement these callback methods to authorize the connection.
New Muxer implementations & container parsing
OggMuxer and WavMuxer
We've added two new dedicated muxers: OggMuxer for muxing OPUS and VORBIS streams into standard .ogg files, and WavMuxer for generating uncompressed and floating-point PCM .wav audio files.
Container parsing and track references
- MP4 Track References (tref):
Mp4Muxer.addTrackReferenceallows linking dependent metadata or aux tracks to primary video streams. - Chapter Extraction: QuickTime and Nero chapter from MP4 files (.m4a, .m4b), and Matroska chapters, are now extracted as Chapter metadata entries for audiobook and podcast navigation.
Please use the issue tracker to report any bugs, or if you have questions or feature requests. We look forward to hearing from you!
August 20th 2026, 7:27 pm
Bring one-handed gestures to your Wear OS app
Android Developers Blog
One-handed gestures offer a convenient and touch-free way for users to interact with their watches, enabling them to perform key actions using only the hand on which the device is worn.
First introduced on Pixel Watch with Wear OS 6.1, one-handed gestures made quick interactions effortless, such as starting and stopping a timer, accepting calls, and controlling media.
Now, with Wear OS 7, we're expanding this functionality with a new Gestures framework that allows OEMs to map gestures to primary actions and dismissals, and an API to bring gesture control to the developer community.
Starting with the 1.7 beta release of Compose for Wear OS, you can seamlessly integrate gesture control into your Wear Compose apps. To use this release, upgrade your Wear Compose dependency to:
androidx.wear.compose:compose-material3:1.7.0-beta01
Designing for one-handed interaction
The one-handed gestures framework is designed around two primary interaction patterns that allow users to take action without touching the screen:
- Primary action, which on Pixel Watch is mapped to a double-pinch gesture: this action should be mapped to the most important task in a given context. For example, users can perform this gesture to take a photo in a camera app, start/stop a timer, or accept an incoming call.
- Dismiss action, which on Pixel Watch is mapped to a wrist turn gesture: this action is mapped to system back by default and provides an intuitive way to close interruptive screens or get back to the watch face. It may be overridden for specific use cases, such as silencing an incoming phone call.
These gestures are currently available on Pixel Watch 3 and newer, and the Wear OS gesture framework is available to all Wear OS device manufactures to adopt.
Check out our new design guidance for integrating one-handed gestures into your Wear app.
Integrating gestures with Compose on Wear OS
To provide seamless gesture support in Wear OS 7, we are introducing a new Modifier.oneHandedGesture that you can apply to any existing interactive composable to make it gesture-aware.
Implementing gestures with Compose on Wear OS requires these steps:
- Define the gesture configuration. Start by using
rememberOneHandedGestureConfigurationto define the nature of the interaction. This configuration dictates the basic behavior by providing theGestureAction(e.g. tracking a primary pinch or a dismiss wrist flick). - Initialize the indicator state. Depending on your UI component, initialize a specific state object, such as
OneHandedGestureClickIndicatorStatefor buttons orOneHandedGestureScrollIndicatorStatefor scrollable lists. This state is used to coordinate visual feedback between the gesture detection modifier and the visual UI indicators, seamlessly managing visibility, timing, and animations. - Apply Modifier.oneHandedGesture to your interactive component. You'll pass in your configuration and state, and you’ll provide standard callbacks:
onGestureAvailableto activate the visual hint when the system prepares the gesture, andonGestureto execute your action when the gesture happens.
The following sample shows how those three steps translate into code when configuring an IconButton:
val gestureConfig = rememberOneHandedGestureConfiguration(action = OneHandedGestureAction.Primary)
val indicatorState = remember { OneHandedGestureClickIndicatorState() }
val coroutineScope = rememberCoroutineScope()
OutlinedIconButton(
onClick = onPlayPauseButtonClicked,
modifier = Modifier.touchTargetAwareSize(IconButtonDefaults.LargeButtonSize)
.oneHandedGesture(
gestureConfiguration = gestureConfig,
interactionSource = interactionSource,
onGestureLabel = "play or pause",
onGestureAvailable = {
coroutineScope.launch { indicatorState.showIndicator() }
},
onGesture = onPlayPauseButtonClicked,
),
) {
// button content goes here
// See "Guided discovery with gesture indicators" section of this post for recommendations on adding a gesture indicator.
}
The GestureAction.Primary can also be used to scroll when the content is the end goal of the user journey, or there is a gesture actionable button off screen that the user can scroll to. Some examples include:
- Scrolling through a notification to view the content and/or initiate a reply (available in
TransformingLazyColumnandScalingLazyColumn). - Paging through workout metrics or other content that doesn’t require the user to tap to continue the user journey (available in
HorizontalPagerandVerticalPager).
val scrollGestureConfig = rememberOneHandedGestureConfiguration(action = GestureAction.Primary)
val scrollIndicatorState = remember { OneHandedGestureScrollIndicatorState() }
val coroutineScope = rememberCoroutineScope()
TransformingLazyColumn(
state = scrollState,
contentPadding = contentPadding,
modifier = Modifier
.fillMaxSize()
.oneHandedGesture(
gestureConfiguration = scrollGestureConfig,
onGestureLabel = "scroll",
onGestureAvailable = {
coroutineScope.launch { scrollIndicatorState.showIndicator() }
},
onGesture = { OneHandedGestureDefaults.scrollDown(scrollState) }
)
) {
// list content goes here
// See "Guided discovery with gesture indicators" section of this post for recommendations on adding a gesture indicator.
}
Guided discovery with gesture indicators
To help users learn which gestures are available, gesture indicators work as hints to help discovery about which gestures are available on a screen.
These hints provide animated cues that inform users where they can perform a gesture. The framework manages the cadence and appearance of these hints, ensuring that they are helpful without being intrusive. System settings let users change the cadence to something less frequent if desired.
To integrate with hints, the API provides the following gesture indicator components:
- the OneHandedGestureClickIndicator for components like a
Button - the OneHandedGestureScrollIndicator component for scrolling
- the OneHandedGestureHorizontalPageIndicator for the
HorizontalPager - the OneHandedGestureVerticalPageIndicator for the
VerticalPager
The following example shows how to use the OneHandedGestureClickIndicator for a Button. See another example for using the OneHandedGestureScrollIndicator in our guidance.
val gestureConfig = rememberOneHandedGestureConfiguration(action = GestureAction.Primary)
val indicatorState = remember { OneHandedGestureClickIndicatorState() }
val coroutineScope = rememberCoroutineScope()
OutlinedIconButton(
onClick = onPlayPauseButtonClicked,
modifier = Modifier.touchTargetAwareSize(IconButtonDefaults.LargeButtonSize)
.oneHandedGesture(
gestureConfiguration = gestureConfig,
interactionSource = interactionSource,
onGestureLabel = "play or pause",
onGestureAvailable = {
coroutineScope.launch { indicatorState.showIndicator() }
},
onGesture = onPlayPauseButtonClicked,
),
) {
OneHandedGestureClickIndicator(
gestureConfiguration = gestureConfig,
indicatorState = indicatorState,
) {
val icon = if (playerUiModel.playbackState.isPlaying) Icons.Filled.Pause else Icons.Filled.PlayArrow
Icon(icon, contentDescription = "Play or Pause")
}
}
We are already seeing early adoption of these APIs from partners like Spotify, who are using one-handed gestures to make music control more seamless on the go. By adopting the Modifier.oneHandedGesture into their Wear OS app, Spotify allows users to play or pause their music with the primary gesture action, which on Pixel Watch devices is the double-pinch gesture. This action triggers the same behavior as the physical play/pause button, and the user doesn’t need to touch the screen.
Bring one-handed gestures to your app
You can begin experimenting with one-handed gestures today in the 1.7 beta release of Compose for Wear OS.
Ensure your app is running on Wear OS 7, which provides the underlying platform support for gesture detection. Check out our new one-handed gestures developer guide to see how you can start building more convenient experiences for your users.
August 20th 2026, 7:27 pm
Tinder cuts app cold starts by 47% with new R8 Configuration Analyzer
Android Developers Blog
Tinder is on a mission to power and inspire real connections by making meeting easy and fun for every new generation of singles. However, as their Android application codebase grew in size, so did its complexity. Prior to their latest optimization efforts, approximately 70% of the application was not optimized, carrying 17 dex files,including three dedicated just to startup. Although they had enabled R8, much of its optimization potential was blocked due to keep rules, and the team was unable to identify which specific rules were preventing optimization. To reduce startup time and decrease user-perceived Application Not Responding (ANR) errors, Tinder turned to the new R8 Configuration Analyzer to tackle these challenges.
By utilizing the R8 Configuration Analyzer, Tinder successfully identified and removed unintentional optimization blockers. The results were immediate and impactful: Tinder achieved a 47% reduction in app cold starts, shrank their app download size by 28.98% (down to 61.5 MB), and reduced user-perceived ANRs by 28%.
Configuration analyzer
The R8 Configuration Analyzer shows R8 optimization by tracking shrinking, optimization, and obfuscation scores to show available refinement areas. It shows the broad, redundant, or obsolete keep rules, including those from external libraries so that you can analyse the keep rule impact and refine the keep rules.
Key metrics shown in Configuration Analyzer include:
- Shrinking Score: Code percentage available for R8 shrinking.
- Optimization Score: Code percentage open to optimization (for example, method inlining, horizontal class merging).
- Obfuscation Score: Percentage of classes, methods and fields that can be renamed by R8 to decrease size.
Use the analyzer to audit keep rules and their impacts:
- Find broad rules: Narrow the scope of package-wide rules that restrict R8 optimization, and identify the specific classes, methods, and fields excluded from shrinking, optimization, and obfuscation.
- Refine rules: Target only specific classes/methods requiring reflection to unlock optimization
- Remove redundant rules: Remove rules that match zero classes, methods, or fields in your current build.
- Identical rules: Identical keep rules means rules that target the same classes, fields, and methods or duplicate declarations of keep rule in same or across keep rule files.
- Find subsumed rules: Clean up specific rules already covered by broader configurations.
- Identify problematic libraries: Check the combined optimization impact of merged consumer keep rules from all libraries.
R8 Configuration Analyzer report of a sample application
To assist you in using the R8 Configuration Analyzer with agentic tools, we have published an R8 Analyzer skill. This skill optimizes automated development workflows by summarizing the R8 Configuration Analyzer report to display key metrics: optimization, obfuscation, and shrinking scores. It also highlights the five most impactful keep rules, giving you clear insight into what blocks code optimization.
Pinpointing hidden optimization blockers
Prior to integrating the R8 Configuration Analyzer, Tinder's Android app suffered from significant technical debt due to a heavily unoptimized codebase. This lack of optimization directly degraded the user experience, leading to users experiencing slow cold starts
To resolve these issues, the Tinder team utilized the R8 Configuration Analyzer to comprehensively audit their R8 configuration. The analyzer showed the R8 optimization of the codebase was around 28% even with R8 full mode. With R8 Configuration Analyzer, Tinder identified that an in-house library was introducing a broad, unscoped keep rule.
# Prevents optimization in all public classes along with all of their public and protected members
-keep public class * {
public protected *;
}
This "wide" rule unintentionally covered various dependencies across the entire app, preventing optimization in a large number of classes. Because the over-inclusive rule prevented runtime crashes, developers frequently missed adding new rules for new features that used reflection, allowing hidden issues to compound over time.
By leveraging the insights provided by the R8 Configuration Analyzer, the team successfully traced and analyzed the specific classes affected by the broad keep rule from the library. The team immediately discovered that optimization was being blocked in larger, non-dynamically invoked classes where R8 could do optimization. Refining this specific keep rule allowed Tinder to unlock substantial optimization capabilities, untangle their legacy configurations, and drastically improve their overall optimization numbers, with R8 scores increasing from 28% to 50%, driving immediate performance gains across the application, and the Tinder team is actively working to further improve this figure.
- Faster Loading: The team achieved a 47% reduction on users experiencing slow cold starts of the app.
- Smaller Footprint: The App download size went from 86.6MB down to 61.5 MB (28.98% decrease).
- Improved Stability: User-perceived Application Not Responding (ANR) errors decreased from 0.35% to 0.28%, bringing them significantly closer to the peer median numbers
- Reduced Complexity: The total number of DEX files was cut down from 17 to 11, including just two startup files.
Beyond these technical performance enhancements, the increased application optimization directly translated into tangible business growth and higher user engagement, particularly in resource-constrained markets.
- Regional Engagement: Countries where Low RAM devices take a huge portion of the market, presented the largest increase in engagement, and decreasing the ANR rates was key to improving engagement in this vast market.
- Engagement Growth: Engagement has increased 3% since the increase in app optimization.
Safeguarding future performance with continuous integration
Addressing code minification isn't just a one-time fix; it requires continuous vigilance. Inspired by the massive gains achieved through the R8 Configuration Analyzer, Tinder’s Android team proactively integrated optimization monitoring into their daily workflow to prevent regressions.
Tinder’s team added a new job in their CI/CD pipeline to report changes in the optimization stats so everyone can see how their contribution is affecting optimization. When advising other developers considering R8 configuration integration, the team emphasizes the importance of auditing internal dependencies. While most popular third-party libraries come with well-defined rules, internal company projects that are considered "stable" might actually be introducing wide rules that negatively impact overall optimization.
Key Takeaways
Faced with a heavily unoptimized codebase and a high volume of DEX files, Tinder needed a way to cleanly audit their app’s minification rules. The R8 Configuration Analyzer provided the ideal tooling necessary to identify overly broad internal library rules, the classes affected by the keep rule, allowing the team to confidently optimize their codebase. As a result, Tinder successfully cut cold starts by nearly half, shrank their APK size by over 28%, and established a healthier, more performant foundation for their users, with the team actively working to further improve these numbers.
How to Use R8 Configuration Analyzer
The R8 Configuration Analyzer and its standalone features can be utilized based on your current Android Gradle Plugin (AGP) version:
- AGP 9.3 Release: The R8 Configuration Analyzer is fully integrated and released with AGP 9.3. When running an R8 release build, the report will be generated in the
build/outputs/mapping/release/configanalyzer.htmlfolder. - Standalone Gradle Task: AGP 9.3 introduces a standalone Gradle task that allows you to generate the analyzer report without running a full release build, providing a much faster feedback loop when refining keep rules locally:
The report is generated at./gradlew :app:analyzeReleaseR8Configbuild/reports/r8/r8-config-analyzer-release.html. - Usage on Older AGP Versions: If you are using a version below AGP 9.3, you do not need to migrate your entire AGP version to analyze your configuration. You can update the R8 version independently to 9.3.7-dev or higher by following the Replacing R8 in AGP instructions. To generate the report locally, run your build with the property specified:
./gradlew assembleRelease -Dcom.android.tools.r8.dumpkeepradiushtmltodirectory=<output_directory>
To learn more, see the R8 Configuration Analyzer documentation.
August 20th 2026, 7:27 pm
Preparing your app for broader memory limits
Android Developers Blog
Posted by Blair Harmon, Director of Product Management, Android Platform
A great user experience is central to Android's mission, and delivering on that promise requires keeping devices fast, responsive, and reliable. This is why memory optimization is more critical than ever. Across the ecosystem, new devices are maintaining or even decreasing their physical memory capacity in response to memory price increases, yet users continue to expect the same seamless, high-performance app experience.
In Android 17, we introduced per-app memory limits, starting with Pixel devices, to help protect the overall user experience from applications using excess memory and causing system-wide slowdowns. Over the coming year, an increasing number of manufacturers will leverage the Android per-app memory limits across their portfolio of device RAM configurations from 4GB to 16GB+ devices. If your app exceeds these limits, it will be slowed down and may be terminated. Optimizing your app's memory footprint is essential to preventing OS throttling and maintaining a seamless user experience.
In this post, we’ll explore how these limits work under the hood, how to measure your memory footprint using new Android vitals metrics, and actionable steps to optimize your app or game.
Understanding Memory Limits
When your app exceeds its memory budget, Android takes progressive action to protect device responsiveness:
- zRAM Swapping: If your app reaches its allocated limit, the system forces your app's pages into zRAM (compressed RAM). While zRAM prevents immediate eviction, compressing and decompressing pages adds CPU overhead, which can result in noticeable UI jank and experience slowdowns.
- Process Termination: If your app continues to increase its memory usage beyond the zRAM threshold, it will be terminated by the system. To determine if your app session was impacted by these constraints in the field, you can call
getDescription()withinApplicationExitInfo. If the system applied a limit, the exit reason is reported asREASON_OTHERand the description string will contain "MemoryLimiter:AnonSwap". You can also leverage trigger-based profiling usingTRIGGER_TYPE_ANOMALYto automatically capture heap dumps when the memory limit is reached.
To learn more about per-app memory limits and system enforcement, review the Android 17 App Memory Limits documentation. To test your application on different device configurations use the Memory Limiter adb commands.
Monitoring and Diagnosing Memory Issues
You can't optimize what you can't measure. Identifying memory leaks, excessive heap allocations, and Out-Of-Memory (OOM) crashes across the Android ecosystem requires leveraging complementary monitoring tools:
- Macro-level health with Android vitals: For broad, population-level visibility without additional overhead, Google Play Console’s Android vitals provides essential metrics like Memory Usage (Anonymous RSS + swap) and Bitmap Memory Usage. This gives you a clear snapshot of memory distribution across different process states (foreground, background, user-perceived services, and cached) and RAM class ranges, helping you spot memory outliers.
- Memory Limiter exits & OOM tracking with Firebase Crashlytics: To stay informed about severe memory degradation before it impacts your key metrics, Crashlytics version 20.1.0 introduces additional debug data to help you catch, prioritize, and fix Out-Of-Memory exceptions and memory limiter kills. Tracking these events alongside custom logs and key-value metadata gives you immediate context into process status when a memory failure occurs.
- In-field traces with ProfilingManager: For teams able to maintain a performance observability framework, the
ProfilingManagerAPI introduced in Android 15 (API level 35) allows your app to programmatically request and collect detailed memory debug artifacts such as Java heap dumps and heap profiles directly from production devices. You can also trigger heap dump captures based on specific system signals, such asTRIGGER_TYPE_OOMandTRIGGER_TYPE_ANOMALY.
Read our documentation to learn more about other memory monitoring techniques.
Summary & What's Next
With Android broadening per-app memory limits across all RAM classes, now is the time to audit your memory footprint:
- Prioritize memory optimizations: Prevent your app from being impacted by app memory limits by using best practices.
- Monitor memory use: Monitor your app’s memory behavior to detect and resolve anomalous behavior.
- Optimize your game: Follow the latest guidance for games and complex multimedia apps to maximize memory savings across process states.
Helpful Resources & References
- Android 17 Behavior Changes: App Memory Limits
- Android Vitals: Memory Usage (RSS + swap metric) and Bitmap Memory Usage
- Android Developers Blog: Prioritizing memory efficiency steps for Android 17
- Developer Guide: Manage your app’s memory
August 20th 2026, 7:27 pm
Optimize for Android (Go edition): Lessons from Google apps - Part 1
Android Developers Blog
Posted by Niharika Arora, Developer Relations Engineer
The Android operating system brings the power of computing to everyone. This vision applies to all users, including those on entry-level phones that face real constraints across data, storage, memory, and more.
This was especially important for us to get right because, when we first announced Android (Go edition) back in 2017, people using low-end phones accounted for 57% of all device shipments globally (IDC Mobile Phone Tracker).
What is Android (Go edition)?
Android (Go edition) is a mobile operating system built for entry-level smartphones with less RAM. Android (Go edition) runs lighter and saves data, enabling Original Equipment Manufacturers (OEMs) to build affordable, entry-level devices that empower people with possibility. RAM requirements are listed below, and for full Android (Go edition) device capability specifications, see this page on our site.Recent Updates
We are constantly making phones powered by Android (Go edition) more accessible with additional performance optimizations and features designed specifically for new & novice internet users, like translation, app switching, and data saving.Below are the recent improvements we made for Android 12:
Why build for Android (Go edition)?
With the fast growing & easily accessible internet, and all the features available at low cost, OEMs and developers are aiming & building their apps specifically for Android (Go edition) devices.Fast forward to today — over 250 million+ people worldwide actively use an Android (Go edition) phone. And also considering the big OEMs like Jio, Samsung, Oppo, Realme etc. building Android (Go edition) devices, there is a need for developers to build apps that perform well especially on Go devices.
But the markets with the fast growing internet and smartphone penetration can have some challenging issues, such as:
- Your app is not starting within the required time limit.
- A lot of features/required capabilities increases your app size
- How to handle memory pressure while working on Go apps?
Optimize your apps for Android (Go edition)
To help your app succeed and deliver the best possible experience in developing markets, we have put together some best practices based on experience building our own Google apps Gboard & Camera from Google.Approach
Optimize App Memory
- Release cache-like memory in onTrimMemory(): onTrimMemory() has always proven useful for an app to trim unneeded memory from its process. To best know an app's current trim level, you can use ActivityManager.getMyMemoryState(RunningAppProcessInfo) and then try to optimize/trim the resources which are not needed.
GBoard used the onTrimMemory() signal to trim unneeded memory while it goes in the background and there is not enough memory to keep as many background processes running as desired, for example, trimming unneeded memory usage from expressions, search, view cache or openable extensions in background. It helped them reduce the number of times being low memory killed and the average background RSS. Resident Set Size(RSS) is basically the portion of memory occupied by your app process that is held in main memory (RAM). To know more about RSS, please refer here.
Typically this is useful for loading large assets or ML models.
- Scheduling tasks which require similar resources(CPU, IO, Memory) appropriately: Concurrent scheduling could lead to multiple memory intensive operations to run in parallel and leading to them competing for resources and exceeding the peak memory usage of the app. The Camera from Google app found multiple problems, ensured a cap to peak memory and further optimized their app by appropriately allocating resources, separating tasks into CPU intensive, low latency tasks(tasks that need to be finished fast for Good UX) & IO tasks. Schedule tasks in right thread pools / executors so they can run on resource constrained devices in a balanced fashion.
- Find & fix memory leaks: Fighting leaks is difficult but there are tools like Android Studio Memory Profiler/Perfetto specifically available to reduce the effort to find and fix memory leaks.
Google apps used the tools to identify and fix memory issues which helped reduce the memory usage/footprint of the app. This reduction allowed other components of the app to run without adding additional memory pressure on the system.
An example from Gboard app is about View leaks
A specific case is caching subviews, like this:
The |keyboardView| might be released at some time, and the |keyButtonA| should be assigned as null appropriately at some time to avoid the view leak.
Lessons learned:
- Always add framework/library updates after analyzing the changes and verifying its impact early on.
- Make sure to release memory before assigning new value to a pointer pointing to other object allocation in heap in Java. (native backend java objects)
For example :
In Java it should be ok to do
GC should clean this up eventually.
if ClassA allocates native resources underneath and doesn't cleanup automatically on finalize(..) and requires caller to call some release(..) method, it needs to be like this
else it will leak native heap memory.
- Optimize your bitmaps: Large images/drawables usually consume more memory in the app. Google apps identified and optimized large bitmaps that are used in their apps.
Lessons learned :
- Prefer Lazy/on-demand initializations of big drawables.
- Release view when necessary.
- Avoid using full colored bitmaps when possible.
For example: Gboard’s glide typing feature needs to show an overlay view with a bitmap of trails, which can only has the alpha channel and apply a color filter for rendering.
A screenshot of glide typing on Gboard
- Check and only set the alpha channel for the bitmap for complex custom views used in the app. This saved them a couple of MBs (per screen size/density).
- While using Glide,
- The ARGB_8888 format has 4 bytes/pixel consumption while RGB_565 has 2 bytes/pixel. Memory footprint gets reduced to half when RGB_565 format is used but using lower bitmap quality comes with a price too. Whether you need alpha values or not, try to fit your case accordingly.
- Configure and use cache wisely when using a 3P lib like Glide for image rendering.
- Try to choose other options for GIFs in your app when building for Android (Go edition) as GIFs take a lot of memory.
- The aapt tool can optimize the image resources placed in res/drawable/ with lossless compression during the build process. For example, the aapt tool can convert a true-color PNG that does not require more than 256 colors to an 8-bit PNG with a color palette. Doing so results in an image of equal quality but a smaller memory footprint. Read more here.
- You can reduce PNG file sizes without losing image quality using tools like pngcrush, pngquant, or zopflipng. All of these tools can reduce PNG file size while preserving the perceptive image quality.
- You could use resizable bitmaps. The Draw 9-patch tool is a WYSIWYG editor included in Android Studio that allows you to create bitmap images that automatically resize to accommodate the contents of the view and the size of the screen. Learn more about the tool here.
Recap
This part of the blog outlines why developers should consider building for Android (Go edition), a standard approach to follow while optimizing their apps and some recommendations & learnings from Google apps to improve their app memory and appropriately allocate resources.In the next part of this blog, we will talk about the best practices on Startup latency, app size and the tools used by Google apps to identify and fix performance issues.
September 8th 2022, 1:06 pm
#WeArePlay | Meet Sam from Chicago. More stories from Peru, Croatia and Estonia.
Android Developers Blog
Posted by Leticia Lago, Developer Marketing
A medical game for doctors, a language game for kids, a scary game for horror lovers and an escape room game for thrill seekers! In this latest batch of #WeArePlay stories, we’re celebrating the founders behind a wonderful variety of games from all over the world. Have a read and get gaming!
- Aldo and Sandro from Peru - founders of Dark Dome. They combine storytelling and art to make thrilling and chilling games, filled with plot twists and jump scares.
- Vladimir, Tomislav and Boris from Croatia - founders of Pine Studio. They won the Indie Games Festival 2021 with their game Cats In Time.
- Kelly, Mikk, Reimo and Madde from Estonia - founders of ALPA kids. Their language games for children have a huge impact on early education and language preservation.
September 7th 2022, 1:26 pm
Privacy Sandbox: Developer Preview 5 is here!
Android Developers Blog
Posted by Fred Chung, Android Developer Relations
Today, we’re releasing the Privacy Sandbox on Android Developer Preview 5 ‒ it’s a major milestone that will become the foundation for upcoming Privacy Sandbox Beta releases.
We appreciate that many of you have tested the Developer Preview and have reported issues and shared your feedback. This feedback has helped us evolve the Privacy Sandbox design. For example, we have modified the SDK Runtime design to allow reflection API usage, and have published additional design proposals on FLEDGE services, mediation, and app-to-web measurement.
Let’s have a look at the specifics in this release.
What’s in Developer Preview 5?
Developer Preview 5 includes additional functionality, data validation enhancements, and API signature changes across the privacy preserving APIs and the SDK Runtime. See the release notes for details.Attribution Reporting API
- Added support for cross app and web measurement and encrypted aggregatable reports.
- Some source and trigger registration response headers have been consolidated for a more simplified design.
FLEDGE on Android API
- To provide up-to-date data for auctions, you can set up a daily fetch URL to update custom audience AdData lists and other metadata.
- This release incorporates various API signature changes and additional parameter validation to ensure robustness. Refer to the release notes for details. Be sure to update the sample code and your test projects using previous Developer Preview releases.
SDK Runtime
- Apps get additional control on runtime enabled SDK lifecycle events, such as when the SDK is unexpectedly terminated by the platform. Implementing the SdkSandboxLifecycleCallback allows the app to take appropriate actions to recover.
- After successfully loading an SDK, apps now have access to an IBinder interface to facilitate 2-way communications with the runtime-enabled SDK.
Topics API
- Updated taxonomy for classification of mobile apps.
AdServices permissions
- App developers must now declare AdServices permissions to access the privacy preserving APIs. Learn more.
In the coming months, we’ll continue to use the Developer Previews to innovate and implement new features. We’ll publish more details about the Beta and these future releases in the coming months.
Get started with Developer Preview 5
With today’s Developer Preview release, we hope to continue working with the industry and developers to get prepared for Privacy Sandbox on Android. The release provides the resources you need to begin early testing of features and share feedback. To get started developing, see instructions to set up the SDK and system images on the emulator or supported Pixel devices.For more information on the Privacy Sandbox on Android Developer Preview, visit the developer site and sign up for our newsletter to receive regular updates.
September 7th 2022, 1:26 pm
Announcing the new guide to Android app modularization
Android Developers Blog
Posted by Miłosz Moczkowski, Developer Relations Engineer, Android
As your app grows in size and complexity, it becomes increasingly difficult to manage, build and scale. One way to address this challenge is a software technique called modular programming, or modularization in short. It’s a practice of organizing a codebase into loosely coupled and independent entities - modules.
We know that modularization has been a hot topic among the Android developers community for quite some time now. Recently, we ran a survey to ask you about your experiences in this topic. 86% of developers said that they work on multi-module codebases regularly, while over 90% stated that modularization is a practice they would recommend considering.All large apps are fundamentally modular, and at Google, we’ve been utilizing modularization to develop our most popular applications such as YouTube, Play Store or Google News. This is what Google News team has to say about this practice:
“Modularity of code is critical to managing complexity, stability, readability, and testability in an ever-growing codebase.”
On the other hand though, over 54% responders mentioned that it’s difficult to find good learning materials on this topic and almost 95% claimed that currently available materials on developer.android.com are insufficient! In response to this popular demand, we’ve launched the guide to Android app modularization. The guide is split into two parts. The overview page gives you a high level, theoretical overview of the matter and addresses the following questions:
- What is modularization?
- What are the benefits of modularizing my codebase?
- What are the things to watch out for when modularizing?
- Is modularization the right technique for you?
- What is the low coupling & high cohesion principle?
- What are the types of modules and their roles?
- How do modules pass data between each other?
To see modularization in action, check out the Now in Android project. It's a fully functional app which has a multi-module codebase, and there's a handy modularization learning journey which outlines what the modules do and how they communicate with each other.
Is this for you?
This modularization guide is targeted to intermediate and advanced developers. The guide focuses on modularization from a software architecture point of view. If you’re a beginner, only starting your Android developer journey, you should familiarize yourself with our guide to app architecture first. Modularization guide assumes you are familiar with our recommended app architecture.
It’s just a beginning
We’re not done yet. With modularization being such a wide topic, the two recently released pages are only a beginning. Help us shape the guidance by giving us feedback and telling us which issues you want us to cover. You can find us on social media or use the documentation issue tracker to report bugs.
September 6th 2022, 1:51 pm
Google Play announces the winners of the Indie Games Festival and the Accelerator class of 2022
Android Developers Blog
Posted by Patricia Correa, Director, Global Developer Marketing
Today, at the finals of our Indie Games Festival, thousands of people came together to celebrate the passion, creativity and innovation of small games studios.
Players, jury members, and industry experts attended the event - hosted in a custom virtual world - where they discovered the finalist games and met the people who made them. They were also the first to find out who the winners are, who will receive prizes and promotions that will help them boost their visibility.At the event we also announced the studios selected to join our Indie Games Accelerator. These companies will receive exclusive education and mentorship over a 10-week virtual program, to help them build and grow successful businesses.
Please join us in congratulating each of the winning games and studios.
Meet the festival winners
Europe
South Korea
Japan
Didn’t make it?
If you missed the event or would like to explore further, you can still log in to the virtual world and discover more about the finalists. Available for a limited time only. Explore now.Stay tuned for more programs helping small games companies grow on Google Play.
September 4th 2022, 7:42 pm
CameraX 1.2 is now in Beta
Android Developers Blog
Posted by Donovan McMurray, CameraX Developer Relations Engineer
As part of Android Jetpack, the CameraX library makes complex camera functionality available in an easy-to-use API, helping you create a best-in-class experience that works consistently across Android versions and devices. As of today, CameraX version 1.2 is officially in Beta. Update from version 1.1 to take advantage of the latest game-changing features: our new ML Kit integration, which can reduce your boilerplate code when using ML Kit in a CameraX app, and Zero-Shutter Lag, which enables faster action shots than were previously possible.These two advanced features are simple to implement with CameraX 1.2, so let’s take a look at each of them in depth.
ML Kit Integration
Google’s ML Kit provides several on-device vision APIs for detecting faces, barcodes, text, objects, and more. We’re making it easier to integrate these APIs with CameraX. Version 1.2 introduces MlKitAnalyzer, an implementation of ImageAnalysis.Analyzer that handles much of the ML Kit setup for you.You can use MlKitAnalyzer with both cameraController and cameraProvider workflows. If you use the cameraController.setImageAnalysisAnalyzer() method, then CameraX can also handle the coordinates transformation between the ML Kit output and your PreviewView.
Here’s a code snippet using setImageAnalysisAnalyzer() to set a BarcodeScanner on a cameraController to detect QR codes. CameraX automatically handles the coordinate transformations when you pass COORDINATE_SYSTEM_VIEW_REFERENCED into the MlKitAnalyzer. (Use COORDINATE_SYSTEM_ORIGINAL to prevent CameraX from applying any coordinate transformations.)
Zero-Shutter Lag
Have you ever lined up the perfect photo, but when you click the shutter button the lag causes you to miss the best moment? CameraX 1.2 offers a solution to this problem by introducing Zero-Shutter Lag.Prior to CameraX 1.2, you could optimize for quality (CAPTURE_MODE_MAXIMIZE_QUALITY) or efficiency (CAPTURE_MODE_MINIMIZE_LATENCY) when calling ImageCapture.Builder.setCaptureMode(). CameraX 1.2 adds a new value (CAPTURE_MODE_ZERO_SHOT_LAG) that reduces latency even further than CAPTURE_MODE_MINIMIZE_LATENCY. Note: for devices that cannot support Zero-Shutter Lag, CameraX will fallback to CAPTURE_MODE_MINIMIZE_LATENCY.
We accomplish this by using a circular buffer of photos. On image capture, we go back in time in the circular buffer to get the frame closest to the actual press of the shutter button. No DeLorean needed. Great Scott!
Here’s an example of how this works in a CameraX app with Preview and ImageCapture use cases:
- Just like any other app with a Preview use case, CameraX sends images from the camera to the UI for the user to see.
- With Zero-Shutter Lag, CameraX also sends images to a circular buffer which holds multiple recent images.
- When the user presses the shutter button, there is inevitably some lag in sending the current camera image to your app. For this reason, Zero-Shutter Lag goes to the circular buffer to fetch an image.
- CameraX finds the photo in the circular buffer closest to the actual time when the user pressed the shutter button, and returns that photo to your app.
Next steps
Check our full release notes for CameraX 1.2 for more details on the features described here and more! If you’re ready to try out CameraX 1.2, update your project’s CameraX dependency to 1.2.0-beta01 (or the latest version at the time you’re reading this).
If you would like to provide feedback on any of these features or CameraX in general, please create a CameraX issue. As always, you can also reach out on our CameraX Discussion Group.
September 4th 2022, 7:42 pm
Celebrating 5 years of Kotlin on Android
Android Developers Blog
Posted by Márton Braun, Developer Relations Engineer
Five years ago, at the 2017 Google I/O Keynote, we did something we had never done before: we announced official support for a new programming language to build Android apps with: Kotlin. It was great to see how excited the Android developer community was about this announcement.
Since then, JetBrains and Google have been collaborating around the development of Kotlin, and the Kotlin Foundation was co-founded by the two companies.
As highlighted in those initial I/O announcements, Kotlin is interoperable, mature, production-ready, and open source. It also has outstanding IDE support, as JetBrains develops both the language and its tooling.
Now, five years have passed since the original announcement. To celebrate the amazing language that now powers modern Android app development, we’re taking a quick look at the journey of Kotlin on Android. This post includes quotes from a handful of people who were involved in making Kotlin on Android a success, who are joining us for this celebration.
Early years
The Kotlin adoption story started before official support from Google, within the Android developer community. The excitement in the community was one of the main reasons to invest in official support.“The decision by Google to add support for Kotlin, I think we underestimate how wild of a notion that was at the time. The odds of another company that size making a similar decision based on community support and enthusiasm is very low.“ (Christina Lee, Android engineer at Pinterest, Kotlin and Android GDE)After the 2017 announcement, Android Studio started shipping with built-in support for Kotlin. Lots of documentation and samples were updated to use Kotlin.
In 2018, we launched the Android KTX libraries, which provide Kotlin-friendly extensions wrapping the APIs of the Android framework and several AndroidX libraries. Tooling improved further, too, with Kotlin-specific live templates, lint checks, and optimizations in R8 and ART. The reference documentation for Android was also published in Kotlin for the first time.
Going Kotlin-first
At Google I/O 2019, we committed to Kotlin-first Android development, further increasing our investments in the language.“If you look at a Kotlin new users graph, you immediately notice the two most significant spikes – one in May 2017 and another in May 2019. We have an inside joke about it: ‘Marketing a programming language is easy. All you have to do is make the largest operating system in the world call it an official language during the annual keynote’” (Egor Tolstoy, Kotlin Product Lead at JetBrains)Being Kotlin-first means that we now design our documentation, samples, training content, new libraries and tools for the Kotlin language first, while still supporting users of the Java programming language.
”Now when we want to start a Jetpack Library, we are writing it in Kotlin unless we have a very, very, very good reason not to do that. It’s clear that Kotlin is the first-class language.” (Yigit Boyar, early proponent of Kotlin within Google, currently leading the development of a handful of Jetpack libraries)
Jetpack Compose, Android’s modern UI toolkit is our greatest commitment to Kotlin so far, as it’s Kotlin-only. It’s powered by a Kotlin compiler plugin, and it makes extensive use of advanced language features like coroutines, top-level functions, and trailing lambdas.
“Kotlin is here to stay and Compose is our bet for the future. Right now, for developers that are starting to learn Android, we’re already recommending the Android Basics with Compose course.” (Florina Muntenescu, Jetpack Compose developer relations lead)Kotlin beyond Android
Even though Kotlin is a great fit for Android, it’s a general-purpose language and not solely for use on Android. For teams within Google, Kotlin is now generally available to use for both Android and server-side projects. Thousands of Google engineers are writing Kotlin code, and our internal codebase contains more than 8.5 million lines of Kotlin code to date. This number has been increasing rapidly as well, doubling year over year.gRPC Kotlin and Kotlin for protocol buffers are examples of Kotlin projects Google uses both in Android apps and on servers that have been open sourced and are now receiving community adoption and contributions. Kotlin is also supported on Google Cloud.
Collaboration with JetBrains
There is close collaboration between JetBrains and Google around the development of Kotlin. The Kotlin Foundation was co-founded by the two companies, and it ensures that the language and ecosystem age well.Google engineers have also been working on improving the compiler and on creating important tooling for the language.
“My team is helping JetBrains with rewriting the Kotlin compiler right now, and we also work on Kotlin Symbol Processing, which is the first compiler-related Kotlin project that’s been completely done at Google. We work more closely with JetBrains than some other parts of Google." (Jeffrey van Gogh, member of the Kotlin Foundation, lead of the Kotlin engineering team at Google)
JetBrains and Google also coordinate new releases of the language and the accompanying tooling so that developers are able to use the latest releases as smoothly as possible.
“The collaboration gets stronger over time, and I’m really excited to see its impact on Kotlin’s future. Our coordinated pre-release checks are getting better and better." (Liliia Abdulina, Kotlin QA team lead at JetBrains)
Learn more and share your own stories
You can read more stories about Kotlin from our interviewees in the accompanying Medium post. We’d also love to hear your stories of learning and adopting Kotlin for Android development! Share them on social media using the hashtag #Hi5KotlinOnAndroid!Finally, let’s appreciate these kind words about Kotlin’s accomplishments to conclude our story.
“Technology can really change people's lives and it can really make people happier at work. We normally focus on ‘there's null safety’ or ‘there's type inference’ or all these other technical parts. But when you take a step back, there's a whole story in there about all of the people who had their passion for coding ignited or reignited because Kotlin is such a wonderful language. It's just so impressive that the team is able to do what they're able to do and that the community is as good as it is." (Christina Lee, Android engineer at Pinterest, GDE for Android and Kotlin)
Have a nice Kotlin on Android!
*Java is a trademark or registered trademark of Oracle and/or its affiliates.
September 4th 2022, 7:42 pm
Precise Improvements: How TikTok Enhanced its Video Social Experience on Android
Android Developers Blog
Posted by The Android Developer Relations team
TL;DR
TikTok serves a wide range of user groups. With users around the world, it’s inevitable that some of them experience network issues such as slow, intermittent, or expensive connectivity. Other users are using entry level devices with limited memory and storage. Ensuring an excellent app experience in all these scenarios is paramount. TikTok's team was able to significantly improve their overall performance by following Android’s performance guidance, and employing their deep understanding of development tools such as Android Gradle Plugin and Jetpack libraries. If you want to learn how the TikTok team improved their app experience to achieve better business performance, please read our business article here.
Intro
TikTok is one of the most popular community-driven entertainment platforms with 1 billion people across the globe publishing and browsing video content every day.
A diverse user base naturally means diverse network bandwidth conditions and devices with different screen sizes, available memory and processing power. All users want a smooth, responsive app experience, no matter which device they use. If the app is slow to load, or playback gets stuck, users will feel frustrated and might abandon the app altogether. To avoid issues like these, the TikTok team continuously tracks the overall app performance through ongoing data monitoring, peer benchmarks, and user surveys.
TikTok is constantly introducing new features. But a rapid increase in functionality sometimes leads to an upsurge in technical requirements. The engineering team identified three reasons that slowed down the app : janky frames, video playback lag, and network issues. To solve these issues, the TikTok team looked to Android tools to start their app improvement journey.
From Discovery to Solution
Reducing app startup time, a smoother user experience with reduced jank and better video playback experience were three major goals that the team prioritized. They also discussed how to measure the effects of performance optimization to prevent the occurrence of regression.
1. Faster startup: refactor startup framework
App startup time is one of the metrics in Android Vitals. Making sure the app startup time is no longer than the Android Vital’s recommendation is the best way to ensure the app loads and starts responding to user activity as quickly as possible. The App Startup library is an Android Jetpack library to help developers initialize app components simply and efficiently.The team studied the App Startup library in depth and refactored the app's startup framework to achieve on-demand loading and meticulous scheduling of components. In order to further reduce the execution time of creating Views on the main thread, the team even used a background thread to load View components asynchronously, thus improving the overall speed of app startup.
TikTok used Simpleperf to analyze the code execution time, and Android Studio's Profiler to monitor the usage of resources such as memory, CPU, and network to optimize I/O, threads, and resource locks.
2. Smoother user interface
To ensure a smoother user interface, the team needed to tackle two challenges: 1) simplify the View hierarchy, so that the app only renders what is necessary on screen, and 2) reduce the number of task executions in each frame so that the app can have a steady frame rate.The TikTok team used the Layout Inspector in Android Studio to pinpoint the unnecessary layout contents. The layout boundaries of each View are clearly visible in the inspector, so the team can easily simplify the View hierarchy of the interface and reduce excessive and unnecessary content drawing.
In many cases, TikTok used doFrame() to perform frame-by-frame tasks. Trying to fit too much work in a single frame will inevitably cause a jank. TikTok's approach was to use allocation algorithms to distribute tasks into different frames to ensure that the application has a steady frame rate.
3. Better video playback experience: reuse resources
TikTok users can create audio and video content in various ways, and different codecs are used to play different types of content. Android provides the MediaCodec class to help access the underlying codec. To further improve the speed of video playback, it is good practice to provide different media player instances for different codecs. The TikTok team created a pool of media player instances throughout the application to neatly provide for various media contents. They even run each media player instance in different threads to minimize interference between one anotherNetwork connection speed is another contributor to video lag . The team tested different solutions, including optimizing connections and reusing sockets, and developed algorithms to dynamically adjust buffer length when streaming content to reduce lag during playback.
They also used on-device video super-resolution to generate high-resolution frames based on low-resolution video content, further improving the quality of video playback without increasing network pressure.
Preloading (loading the next video ahead of time) and pre-rendering (rendering the first frame of the video ahead of time) are critical components to ensure that users have a smooth experience when playing multiple videos in succession. TikTok drew a Surface in advance only adding it into the screen when it is actually needed, to reduce the pressure of drawing it on the spot.
4. Avoid regressions
The team continues to maintain a detailed understanding of performance and works to fine-tune elements when necessary. Luckily, Android has tools in place for this exact purpose, like Systrace to capture traces so developers can export system activities (including CPU scheduling, disk activities, and app threads) for detailed analysis. The team also relies heavily on tools like Perfetto and Android Studio CPU profiler to track the execution time of various events, especially for I/O and class loading.Better Performance, Better Experience
TikTok creatively leveraged the Android toolchain to track, quantify, and optimize their app’s performance for its business priorities, resulting in improved user experience and an increase in user satisfaction
The app startup time was reduced by 45%, and the smoothness (the chance of the frame rate being lower than the target value) has been optimized by 49%. When playing a video, the first frame of the video appeared 41% faster, and the chance of video lag was reduced by 27%.
Users are now more willing to use TikTok: active days per user in 30 days increased by 1%as did the average of session duration. User surveys and TikTok’s rating in Google Play also show a significant increase in user satisfaction.
The Next Stage for TikTok
By constantly optimizing app performance and adapting to the latest Android 13 platform, TikTok has created a more seamless app experience, encouraging more users to discover, create, and share the content they love.
With more than 250 million active large-screen Android devices globally, the team has also been focusing on large-screen devices, including foldable devices. By adopting the app to large screens, the team has brought a more immersive experience to TikTok users.
To learn more about how TikTok optimized its Android app to improve user experience and business performance, read the article here.
Get Guidance on Performance
September 4th 2022, 7:38 pm
Monitor all your deep links in one place on this new Play Console page
Android Developers Blog
Posted by Yafit Becher, Product Manager, Google Play and Luís Dorelli, Engineer, Google Play
Deep links are a great way to improve engagement with your in-app content and the overall user experience by accepting traffic from external sources, including the web. Keeping your deep links in good shape, however, can be a challenge, so many apps have partial, broken, or no deep links configured. For some developers, even answering basic questions like “is this URL deep-linked?” or “why is this deep link not working?” can be difficult to answer.
That’s why we’re making it easier for you to keep your deep links in good shape with a new, dedicated Play Console page. This page collects all the information and tools related to your app’s deep links in one convenient place, giving you a quick but comprehensive snapshot of your current setup to help you identify and troubleshoot issues at a glance.
| See a comprehensive snapshot of your deep links so you can easily identify and troubleshoot issues. |
Get step-by-step guidance on how to fix issues with your deep links. |
Lastly, the new deep links page offers a full drill-down of your deep links app configuration, listing details of all intent filters and the sources they are configured to receive traffic from. Again, you can see if each line item is properly configured, and if not, get specific instructions about how to fix it.
We’re very excited to share this first release of the deep links page with you, making it much easier to make sense of your setup and fix broken deep links. The next release, coming later this year, will also highlight important website URLs that aren’t yet configured as deep links, so that you don’t miss an opportunity to drive more quality traffic to your app.
Check out the new deep links page today to see the status of your deep links and fix any setup issues.
September 4th 2022, 7:38 pm
Google Play Coffee break with iMumz | From start-up to scale-up
Android Developers Blog
Today I’m excited to announce that we are launching the second episode of Google Play Coffee breaks. In this episode I enjoyed a virtual coffee with Ravi Teja Akondi, co-founder and CEO of iMumz. iMumz caters to expecting and new parents to help them practice wellbeing and mindfulness during the early stages of parenthood. Ravi and his team recently graduated from Appscale Academy, an initiative aimed at supporting promising Indian app start-ups and helping them grow into global businesses. It’s great to see their continued growth and to hear them share tips and learnings they picked up along the way.
Watch the full Coffee breaks episode and get my take on it below:
The team at iMumz created their app with the mission to help expecting and new parents easily follow a healthy lifestyle every day, encouraging them to practice mindfulness daily. The app provides support to parents focusing on well-being during the first 1,000 days of pregnancy; that is 270 days of pregnancy and the first two years of parenthood. Today, the app helps over 600,000 people achieve these goals.
Ravi recalled how in the early days the iMumz team sent out actionable insights to their audience via a messenger app. They started by customizing small daily routines for those seeking to learn more about wellness during pregnancy and parenthood. By tracking the completion rates and retention rates, the team were able to see that they were really creating something valuable and gained the confidence to take the business from a messaging service to a full mobile application.
Growing a sustainable business
The first step for the iMumz team was to work on building out a community of early adopters. After conducting initial market research the team realized those in tier one cities - the metro cities in India - were the most likely to become early adopters. As they expanded to more and more parents, they learnt how important it was to tailor their pricing to different types of audiences. Experimentation was key to understanding what their different audiences were willing to pay. Remember that beyond the really useful data you can gather from running experiments, you can also get incredibly valuable direct and written feedback from users by inviting them into closed testing groups you can easily set up in the Play Console, without this feedback impacting your star rating.Nurturing your app community
Through experimenting and listening to users, iMumz learnt that parents-to-be wanted to connect with others like them, and the team quickly realized that the people using their app needed a community. People wanted to connect with others going through similar life events. By building out community spaces the team was able to help initiate discussions on specific topics; such as breastfeeding, baby-led weaning, and self care postpartum. The community has since helped important conversations develop naturally, and provides iMumz users with another level of peer support. Today, their community is vibrant, with more than 5,000 conversations taking place every day!When it comes to building out a community it’s important that your messaging to users feels genuine and authentic. This was especially important for iMumz, given the app caters to a sensitive and important set of life moments for parents. To start, as with any message, making message content relevant and timely is critical. For example, consider the time of day when determining the best time to post new content, updates, or sending push notifications, and remember different time zones when you’re dealing with a global audience. Additionally, it can help to put a relatable person or character behind the message (remember to localize this to your audience though).
Ravi also shared two key learnings he felt made the biggest difference to the growth of his app:
1) Experiment. There are so many ideas you might find counterintuitive - don’t automatically discount any or jump to conclusions until you test them. Be data driven. That's going to help you provide more value, faster.
2) Narrow down what you’re working on, so you focus on one task or challenge at a time. You might be tempted to do many things at once, but narrowing down will help give you amplified results.
To where does the future lead?
It was such a pleasure to speak to Ravi about his experiences and I can’t wait to see iMumz’s continued growth and next steps. I get so much inspiration from speaking with the people behind apps like iMumz, and I know that inspires my team to continue investing in and developing initiatives such as Appscale Academy.
We are looking forward to continuing to learn from more businesses, and see what you all do next. Stay tuned for the next episode of Coffee Breaks.
- Tamzin Taylor, Head of Play Partnerships, Western Europe
September 4th 2022, 7:38 pm
Announcing Cross device SDK Developer Preview for building rich multi-device experiences on Android
Android Developers Blog
Posted by Alex Rocha - Developer Relations Engineer Manager, Ryan Ausanka-Crues - Eng Manager, Multi-device development, Stella Loh - Product Manager, Multi-device development
Today we’re launching our Developer Preview of the new Cross device SDK for Android. First announced during the Google I/O ‘22 Multi-device development session, our Cross device SDK allows developers to build rich multi-device experiences with a simple and intuitive set of APIs. This SDK abstracts away the intricacies involved with working with device discovery, authentication, and connection protocols, allowing you to focus on what matters most—building delightful user experiences and connecting these experiences across a variety of form factors and platforms.
What’s in Developer Preview
This initial release contains a set of rich APIs centered around the core functionality of Device discovery, Secure connections, and Multi-device Sessions.
- Device discovery: Easily find nearby devices, authorize peer-to-peer communication, and start the target application on receiving devices.
- Secure connections: Enable encrypted, low-latency bi-directional data sharing between authorized devices.
- Multi-device Sessions: Enable transferring or extending an application’s user experience across multiple devices.
In turn, this will allow you to build compelling cross-device experiences by enabling and simplifying the following use cases:
- Discovering and authorizing communication with nearby devices.
- Sharing an app’s current state with the same app on another device.
- Starting the app on a secondary device without having to keep the app running in background.
- Establishing secure connections for devices to communicate with each other.
- Enabling task handoff where the user starts a task on one device, and can easily continue on another device.
Starting today with a Developer Preview for Android phones and tablets, the Cross device SDK will be available later for other Android surfaces and non-Android OSs.
Under The Hood
The Cross device SDK provides a software abstraction layer that handles all aspects of cross-device connectivity, leveraging wireless technologies such as Bluetooth, Wi-Fi, and Ultra-wide band; our SDK does all the heavy-lifting under the hood, offering you a modular,connectivity-agnostic API that supports bi-directional communication between devices and is backward compatible to Android 8. In addition, apps will not have to declare or request Runtime Permissions for any of the underlying connectivity protocols used (such as BLUETOOTH_CONNECT, BLUETOOTH_SCAN, ACCESS_FINE_LOCATION, etc.), and the user can allow apps to connect to only the device(s) they selected.
Getting started with Developer Preview
Head over to our developer guide to get started and try out the Developer Preview of the Cross device SDK for Android. Make sure to check out our Rock Paper Scissor sample app (Kotlin and Java) on GitHub for a demonstration on how to work with the various APIs and our Google I/O ‘22 Multi-device development session for a general overview of the SDK.
Feedback
We’d love to hear from you during this initial Developer Preview launch to help us shape the SDK and influence future roadmapping, so please share your feedback and let us know your experience with the SDK!
September 4th 2022, 7:38 pm
#WeArePlay | Meet George from the UK. More stories from Croatia, USA and Kenya.
Android Developers Blog
Posted by Leticia Lago, Developer Marketing
Our celebration of app and game businesses continues with more #WeArePlay stories. Today, we’re starting with George from Bristol, UK - a young entrepreneur taking the streetwear industry by storm.After spending hours and hours searching for the latest styles in sneakers and streetwear, George realised there’s a market in helping fellow enthusiasts find the latest drops. At just 16 years old, he took it upon himself to learn to code and created his app, Droplist. It points people to upcoming special collections from major labels around the world. Find out more about his story.
- Anica and Kristijan from an island in Croatia - founders of Dub Studio Productions to help music lovers around the global turn up the bass or lower the treble on their favourite songs.
- Robert from Wyoming, founder of Bluebird Languages - language learning apps with over 6 million hours of audio lessons spanning 164 languages, from Hungarian to Haitian Creole.
- And one more new story - because why not! This time, featuring Annabel from Kenya. After struggling to find a mechanic when stuck on the roadside in Nairobi, she and her co-founder created Ziada to help people find local service providers.
September 4th 2022, 7:38 pm
Android 13 is in AOSP!
Android Developers Blog
Today we’re pushing the Android 13 source to the Android Open Source Project (AOSP) and officially releasing the newest version of Android. For developers, Android 13 is focused on our core themes of privacy and security as well as developer productivity, making it easier for you to build great experiences for users. We’ve also continued to make Android an even better OS for tablets and large screens, giving you better tools to take advantage of the 270+ million of these devices in use across the world. You can read more about Android 13 for consumers in our Keyword blog post
Android 13 is rolling out to Pixel devices starting today. Later this year, Android 13 will also roll out to more of your favorite devices from Samsung Galaxy, Asus, HMD (Nokia phones), iQOO, Motorola, OnePlus, Oppo, Realme, Sharp, Sony, Tecno, vivo, Xiaomi and more.
As always, we thank you for the feedback you’ve shared, and we appreciate the work you’ve done to make your apps compatible with today’s release. Your support and contributions are what make Android a great platform for everyone!
What’s in Android 13 for developers?
Here’s a look at some of what’s new in Android 13 - make sure to check out the Android 13 developer site for details on all of the new features.Developer productivity and tools
Themed app icons - Android 13 extends Material You dynamic color to all app icons, letting users opt-in to icons that inherit the tint of their wallpaper and other theme preferences. All your app needs to supply is a monochromatic app icon and a tweak to the adaptive icon XML. More here.
| Themed app icons adapting to wallpapers colors and dark theme (left). |
Per-app language preferences - Android 13 makes it easier to support multilingual users who want to use your apps in a language that’s different from the system language. Android now provides a standard “App language” Settings panel for apps that have opted-in, and you can call a new platform API to get or set the user’s preferred locale at runtime, helping to reduce boilerplate code and improve compatibility. More here.
| Per-app languages in Settings |
Improved text support - Android 13 includes text and language improvements that help you deliver a more polished experience. Faster hyphenation optimizes hyphenation performance by as much as 200% so you can now enable it in your TextViews with almost no impact on rendering performance. Text conversion APIs make searching and autocompletion faster when using phonetic lettering input for languages like Japanese, Chinese, and others. Android 13 also improves line heights for non-latin scripts (such as Tamil, Burmese, Telugu, and Tibetan), eliminating clipping and making them easier to read. More here.
| Improved line height for non-Latin scripts in apps targeting Android 13 (bottom). |
COLRv1 vector emoji (left) and bitmap emoji. |
Programmable shaders - Android 13 introduces programmable RuntimeShader objects, with behavior defined using the Android Graphics Shading Language (AGSL). You can use these shaders to create ripple, blur, stretch, and similar advanced effects in your apps. More here.
Media controls derived from PlaybackState - For apps targeting Android 13, the system now derives media controls from PlaybackState actions, providing a richer set of controls that are consistent across phones and tablet devices and align with other Android platforms such as Android Auto and Android TV. More here.
Android 13 media controls are consistent on phones and tablets. |
Bluetooth LE Audio - Low Energy (LE) Audio is the next-generation wireless audio built to enable new use cases like sharing and broadcasting audio to friends and family, or subscribing to public broadcasts for information, entertainment, or accessibility. It’s designed to ensure that users can receive high fidelity audio without sacrificing battery life, and lets them seamlessly switch between different use cases. Android 13 adds built-in support for LE Audio, so developers can use the new capabilities on compatible devices. More here.
MIDI 2.0 - Android 13 adds support for the new MIDI 2.0 standard, including the ability to connect MIDI 2.0 hardware through USB. This updated standard offers features such as increased resolution for controllers, better support for non-Western intonation, and more expressive performance using per-note controllers. More here.
OpenJDK 11 updates - Android 13 Core Libraries now align with the OpenJDK 11 LTS release, with both library updates and Java 11 programming language support for app and platform developers. We plan to bring these Core Library changes to more devices through Google Play system updates, as part of an ART module update for devices running Android 12 and higher. More here.
Predictive back gesture - Android 13 introduces new APIs that let your app tell the system that it will handle back events in advance, a practice we call the "ahead-of-time" model. This new approach is part of a multi-year effort to help you prepare your app to support the predictive back gesture, which is available for testing in this release through a developer option. More here.
Built for tablets
Android 13 extends the 12L update that we released earlier this year, and it delivers an even better experience on tablets. You’ll find features like an enhanced multitasking taskbar, more large-screen layouts and optimizations in system UI and apps, improved compatibility modes for apps, and more. We’re continuing to invest to give you the tools you need to build great experiences for tablets as well as Chromebooks and foldables. You can learn more about how to get started optimizing for large screens, and be sure to check out our large screens developer resources.
| Multitasking on tablets with Android 13. |
Privacy and security
Photo picker and APIs - A new system photo picker now gives users a standard, privacy-protecting way to share local and cloud-based photos. Photo picker extends Android’s long-standing document picker and makes it easy for users to share specific photos and videos with an app, without giving the app permission to view all media files on the device. Photo picker provides a dedicated experience for photos and videos and includes APIs for apps to access the shared media files. The photo picker experience is now available to users who receive Google Play system updates, on devices (excepting Go devices) running Android 11 and higher. More here.Photo picker lets users share specific photos and videos with an app. |
| Notification permission dialog in Android 13. |
Nearby device permission for Wi-Fi - Android 13 introduces the NEARBY_WIFI_DEVICES runtime permission for apps that manage a device's connections to nearby access points over Wi-Fi. The new permission is required for many commonly-used Wi-Fi APIs and enables apps to discover and connect to nearby devices over Wi-Fi without also needing to acquire the location permission. More here.
Granular permissions for media file access - Photo picker is our recommended solution for user-friendly, permissionless sharing of photos and videos, but for apps that haven’t moved to photo picker yet or for audio use cases, Android 13 adds new granular media permissions. These new permissions replace the READ_EXTERNAL_STORAGE permission and provide access to specific types of media files, including images, video, or audio. We highly recommend moving your app to photo picker if possible; otherwise, use the granular media permissions when targeting Android 13. More here.
| Requesting permission to access audio files. |
Developer downgradable permissions - Starting in Android 13, apps that no longer require permissions previously granted by the user can use a new API to downgrade the permissions. By removing unused permissions, your app can show that it’s using the minimum permissions needed, which can improve user trust. More here.
Safer exported Intent filters - Android 13 applies stricter rules when delivering explicit intents to exported intent filters in another app that’s targeting Android 13. For intents that specify actions, the system now delivers the intents to the exported component only if the intent matches the receiver’s declared <intent-filter> elements. More here.
Performance for apps
Android 13 improves performance and efficiency for all apps through updates to the ART runtime. We plan to bring these improvements to more Android users through Google Play system updates, as part of our ongoing ART module updates for devices running Android 12 and higher.Improved garbage collection - A new garbage collector based on the Linux kernel feature userfaultfd is coming to ART on Android 13 devices in an upcoming Google Play system update. The new garbage collector eliminates the read barrier and its fixed overhead per object loaded, reducing memory pressure and leading to as much as ~10% reduction in compiled code size. It’s more efficient at GC-time as well, since pages are freed as compaction progresses. Overall, the new garbage collector helps to save battery, avoid jank during GC operations, and protect apps from low-memory kills.
Optimizations throughout ART - In Android 13, ART makes switching to and from native code much faster, with JNI calls now up to 2.5x faster. We’ve also reworked the runtime’s reference processing to make it mostly non-blocking, which further reduces jank. We’ve exposed a new public API, Reference.refersTo(), which is useful in reclaiming unreachable objects sooner, and we’ve made the interpreter faster by optimizing class/method lookups. Lastly, ART now performs more byte-code verification at install time, avoiding the expense of verification at runtime and keeping app startup times fast. More here.
Get your apps ready!
Now with today’s public release of Android 13 to AOSP, we’re asking all Android developers to finish your compatibility testing and publish your updates as soon as possible, to give your users a smooth transition to Android 13.To test your app for compatibility, just install it on a device running Android 13 and work through the app flows looking for any functional or UI issues. Review the Android 13 behavior changes for all apps first, to focus on areas where your current app could be affected. Here are some of the top changes to test:
- Notifications runtime permission - Make sure you understand how this new permission works with your app’s notifications, and plan on targeting Android 13 (API 33) as soon as possible to help support users. More here.
- Clipboard preview - Make sure your app hides sensitive data in Android 13’s new clipboard preview, such as passwords or credit card information. More here.
- JobScheduler prefetch - JobScheduler now tries to anticipate the next time your app will be launched and will run any associated prefetch jobs ahead of that time. If you use prefetch jobs, test that they are working as expected. More here.
Once you’ve published the compatible version of your current app, you can start the process to update your app's targetSdkVersion. Review the behavior changes for apps targeting Android 13 for this, and use the compatibility framework to help detect issues quickly.
Tablet and large-screens support
With Android 13 bringing a better experience to tablets, make sure your apps look their best. You can test large-screen features by setting up an Android emulator in Android Studio, or you can use a large screen device from our Android 13 Beta partners. Here are some areas to watch for:- Taskbar interaction - Check how your app responds when viewed with the new taskbar on large screens. Make sure your app's UI isn't cut off or blocked by the taskbar. More here.
- Multi-window mode - Multi-window mode is now enabled by default for all apps, regardless of app configuration, so make sure the app handles split-screen appropriately. You can test by dragging and dropping your app into split-screen mode and adjusting the window size. More here.
- Improved compatibility experience - if your app isn’t optimized for tablets yet, such as using a fixed orientation or not being resizable, check how your app responds to compatibility mode adjustments such as letterboxing. More here.
- Media projection - If your app uses media projection, check how your app responds while playing back, streaming, or casting media on large screens. Be sure to account for device posture changes on foldable devices as well. More here.
- Camera preview - For camera apps, check how your camera preview UI responds on large screens when your app is constrained to a portion of the screen in multi-window or split-screen mode. Also check how your app responds when a foldable device's posture changes. More here.
What’s next?
Android 13 is rolling out to Pixel devices starting today.If you’re currently enrolled in the Android Beta program, you’ll get the Android 13 final release and remain enrolled to receive ongoing Beta updates for Android 13 feature drops, starting later this year. If you’d like to opt out of ongoing Beta updates without needing to wipe your device, just visit the Android Beta site and opt out after you get the Android 13 final release and before taking the first beta for Android 13 feature drops.
System images for Pixel devices are available here for manual download and flash, and you can get the latest Android Emulator system images via the SDK Manager in Android Studio. If you're looking for the Android 13 source, you'll find it here in the Android Open Source Project repository under the Android 13 branches.
Thanks again for participating in our program of early previews and Betas! We're looking forward to seeing your apps on Android 13!
Java and OpenJDK are trademarks or registered trademarks of Oracle and/or its affiliates.
تحميل تطبيق نبأ للآندرويد مجانا




























.png)
.jpg)






.png)

.jpg)



.png)



.png.jpeg)
.png)





.png.jpeg)








.jpg)

.png)






.png)







.png)
.png)






تحميل تطبيق نبأ للآندرويد مجانا