DEV Community

Shantanu Gonade
Shantanu Gonade

Posted on • Originally published at Medium on

Android After Google I/O 2026

Edge-to-edge is mandatory. Predictive back now owns your stack. Compose 1.11 ships Grid and Styles. Navigation 3 is stable. Kotlin 2.4 context parameters are production-ready.

Android After Google I/O 2026

If your app targets Android 16 (API 36), two things will break the moment a user upgrades: your status bar layout and your back button handler. Not "might break." Will break.

Google I/O 2026 has a single through-line: Android is now Compose-first. That phrase showed up in every keynote. It isn't marketing. It means Google is putting all future guidance, new APIs, and tooling investment behind Jetpack Compose. Five years after its launch, Compose has graduated from "recommended" to "the only supported path forward." Every change in this article connects back to that shift.

Let's start with what's on fire.

Two Things That Will Break Your App Right Now

Edge-to-Edge Is No Longer Optional

Left: not edge-to-edge. Right: edge-to-edge — the only mode Android 16 supports.

Left: not edge-to-edge. Right: edge-to-edge — the only mode Android 16 supports.

Starting with Android 16 (API level 36), the system ignores WindowCompat.setDecorFitsSystemWindows(window, false). Apps that used true to opt out of edge-to-edge will now render incorrectly — content bleeds behind the navigation bar and status bar without insets applied.

Edge-to-edge is enforced. There is no opt-out flag, no manifest attribute to escape it. You must handle window insets explicitly.

Here is the correct pattern for a full-screen composable in 2026:

Mandatory Edge-to-Edge Activity initialization for apps targeting Android 16 (API 36) using Jetpack Compose.

The enableEdgeToEdge() call replaces the old WindowCompat dance. It sets the correct window appearance flags, handles light/dark status bar icons, and prepares the window for inset consumption.

Inside your screens, use Modifier.consumeWindowInsets and the WindowInsets APIs directly rather than relying on Scaffold to absorb everything silently:

Proper window insets consumption using Scaffold and WindowInsets.safeContent in Jetpack Compose.

The key mistake developers make is passing WindowInsets.Zero to contentWindowInsets to "fix" visual issues, which defeats the purpose of edge-to-edge and creates problems on devices with gesture navigation. Use WindowInsets.safeContent and let the system compose correctly.

Gesture insets: the green zones are controlled by the OS. Never place tappable targets under them.

Gesture insets: the green zones are controlled by the OS. Never place tappable targets under them.

If you have custom views inside a AndroidView composable, apply insets explicitly:

Applying system bar window insets manually to a legacy Android View inside an AndroidView composable wrapper.

Migration checklist:

  • Replace all WindowCompat.setDecorFitsSystemWindows(window, true) calls with enableEdgeToEdge()
  • Replace WindowCompat.setDecorFitsSystemWindows(window, false) calls — they are now no-ops
  • Audit every Scaffold for missing contentWindowInsets
  • Test on a device running Android 16 with gesture navigation enabled

Predictive Back: onBackPressed Is Dead

Predictive back previews the destination before the gesture commits. On Android 16, your app must support this natively.

Predictive back previews the destination before the gesture commits. On Android 16, your app must support this natively.

On Android 16 (API 36), onBackPressed() is no longer called. KeyEvent.KEYCODE_BACK is not dispatched. If you override onBackPressed in an Activity or Fragment and you have not migrated to the predictive back APIs, your back handling silently does nothing.

This is a hard breaking change, not a deprecation warning.

The correct implementation uses BackHandler in Compose, which wires into the OnBackPressedDispatcher — the only supported path:

Intercepting system back gestures with BackHandler and AnimatedContent in a multi-step Jetpack Compose form wizard.

For the system's predictive back preview animation — the one that shows a shrinking card as you swipe — you get it for free when you use BackHandler. The system intercepts the gesture and shows the preview before your handler fires. You do not write animation code for the default behavior.

Motion spec during a left-edge swipe: the surface scales to 90%, shifts right with an 8dp margin. PredictiveBackHandler gives you the progress value to drive this.

Motion spec during a left-edge swipe: the surface scales to 90%, shifts right with an 8dp margin. `PredictiveBackHandler` gives you the progress value to drive this.

For custom back animations (your own content transitioning while the user is mid-swipe), use PredictiveBackHandler:

Driving bespoke screen scale and translation animations using PredictiveBackHandler progress events in Jetpack Compose.

If you still have legacy code that uses onBackPressed, set android:enableOnBackInvokedCallback="false" in your manifest as a temporary escape hatch — but treat it as technical debt with a deadline. It will not be supported forever.

Kotlin 2.4: Context Parameters Are Stable and They'll Change How You Write Compose Code

Kotlin 2.4.0 release notes: context parameters are stable. No compiler flags required.

Kotlin 2.4.0 release notes: context parameters are stable. No compiler flags required.

Kotlin 2.4.0, released in June 2026, promotes context parameters to stable. No compiler flags required. Production-ready today.

Context parameters let a function declare that it needs a value to be "in scope" without the caller explicitly passing it. The compiler injects the dependency from the surrounding scope.

Here is the problem they solve in a Compose codebase. Consider a common pattern — a function that needs both a SnackbarHostState and a CoroutineScope to show snackbar messages:

The old way (lots of plumbing):

Explicitly plumbing SnackbarHostState and CoroutineScope parameters across multiple Compose layout functions (Antipattern).

The new way with context parameters:

Leveraging stable Kotlin 2.4 context parameters to eliminate ambient parameter drilling in Compose UI functions.

The stronger use case: domain-level operations that need infrastructure — logging, analytics, navigation — without threading those concerns through every parameter.

Context parameters work especially well with the NowInAndroid architecture pattern. In a repository that needs both a network client and a local DAO, context parameters let you declare those dependencies at the call site rather than injecting them into the constructor when the caller already has them in scope.

Declaring infrastructure dependencies at the call-site of a Repository using Kotlin 2.4 context parameters.

This is not a replacement for Hilt or dependency injection. Context parameters solve a different problem: eliminating parameter drilling for values that are ambient within a call chain, not values that are injected at construction time.

Compose 1.11: Grid, Styles, and the Testing Overhaul

The Grid API

Compose 1.11 ships a non-scrollable Grid composable for building two-dimensional layouts. This is different from LazyVerticalGridGrid is for fixed-size layouts, not infinite lists.

Before Grid, building a dashboard-style layout in Compose required either LazyVerticalGrid (wrong — it's built for infinite content and has overhead for fixed layouts) or nested Row/Column composables (fragile and hard to maintain).

Creating fixed-size dashboard UIs with the Compose 1.11 non-scrollable Grid API and GridItemSpan column spanning.

The GridItemSpan API gives you column-spanning without the SubcomposeLayout gymnastics that were previously required.

The Styles API (Experimental)

The experimental Style {} API separates a component's visual appearance from its structural behavior. Instead of overriding colors, shapes, and textStyle through individual parameters, you declare a style object that carries all visual customization.

Separating layout structure from visual customization using the experimental Compose 1.11 Style component API.

The Styles API is still @ExperimentalFoundationApi in 1.11. Do not ship it in production without understanding that the API surface may change. It is worth understanding now because this is the direction Compose is moving for design system work.

The Testing API Overhaul

Compose 1.11 makes the v2 testing APIs the default. This is a breaking change for test suites that relied on the implicit coroutine execution behavior of v1.

What changed: v1 tests used UnconfinedTestDispatcher, which ran coroutines immediately when launched. v2 uses StandardTestDispatcher, which queues coroutines. They run only when you advance the virtual clock.

Broken asynchronous test pattern under Compose 1.11 due to queued StandardTestDispatcher behavior.

The migration is mechanical: find every runComposeUiTest block that asserts on asynchronous state and add mainClock.advanceUntilIdle() or mainClock.advanceTimeBy(timeMs) after setContent. If you are using waitUntil, review whether it is masking timing assumptions.

The v1 APIs are deprecated but still present in 1.11. They will be removed in a future release.

Navigation 3 Is Stable. Time to Migrate.

Navigation 3's NavDisplay handles back-gesture insets automatically. No manual inset wiring required.

Navigation 3's `NavDisplay` handles back-gesture insets automatically. No manual inset wiring required.

Jetpack Navigation 3 reached stable in late 2025 and is now the official navigation library for Compose apps. Navigation 2 (androidx.navigation:navigation-compose) still works, but it will not receive new features.

Navigation 3 does one thing Navigation 2 never could: it gives you full ownership of the back stack as state. The back stack is a List<Any> that you hold in a MutableList — a plain Kotlin value. Navigation observes it; it does not own it.

Migration from Navigation 2 to Navigation 3:

Before:
Application navigation routing structure using explicit NavHost string definitions in Jetpack Navigation 2.
After:
Defining type-safe route keys and managing the backstack as observable state using Jetpack Navigation 3.

The back stack is a SnapshotStateList<NavKey>. You can read it, filter it, replace entries, and serialize it for process death restoration — none of which was possible with NavController.

Adaptive layouts with Navigation 3:

Navigation 3's architecture makes two-pane layouts straightforward. The same back stack drives both single-pane (phone) and two-pane (tablet/foldable) layouts:

Adapting a single navigation state backstack natively for single-pane (mobile) and dual-pane (tablet) Android devices.

This pattern — a single back stack that adapts its display — is the official recommended approach for large-screen apps in 2026.

The Platform Goes Compose-First: Widgets, Camera, and Health Connect

Jetpack Glance + RemoteCompose: Widgets Are Finally Good

The same Compose concepts that govern app UI now govern widget UI via Jetpack Glance + RemoteCompose.

The same Compose concepts that govern app UI now govern widget UI via Jetpack Glance + RemoteCompose.

Android 17 marks a shift toward a Compose-based development model for all widgets. The vehicle is RemoteCompose, integrated into Jetpack Glance.

RemoteCompose renders full Compose animations on remote surfaces — home screen widgets and car displays. This means your home screen widget can have animated progress indicators, state transitions, and dynamic content without the RemoteViews limitations that made widget development miserable for a decade.

Building home screen widgets featuring live progress animations using Jetpack Glance and RemoteCompose.

This is the first time CircularProgressIndicator in a widget animates properly on the home screen without running a background service to push RemoteViews updates at a fixed interval.

Health Connect: FHIR Medical Records

Health Connect in Android 16 adds write access for medical records in FHIR (Fast Healthcare Interoperability Resources) format. Health Connect is no longer just fitness data.

Saving Fast Healthcare Interoperability Resources (FHIR) medical documentation data inside Android 16 Health Connect.

Apps that read FHIR records must declare READ_MEDICAL_DATA_* permissions (scoped per category). The Health Connect permission dialog now shows users exactly what medical categories an app requests. This is a significant privacy surface — do not request medical permissions unless your app requires them.

CameraX: The Composable Viewfinder

CameraXViewfinder is now a stable @Composable that replaces the old XML-only PreviewView. It handles rotation, surface lifecycle, and camera configuration correctly across all window sizes.

Lifecycle-aware viewfinder rendering using CameraXViewfinder and a continuous capture controller overlay.

The old pattern required wrapping PreviewView in AndroidView, which created lifecycle coordination issues when the composable was paused. CameraXViewfinder handles this correctly.

Your Toolchain Changed Completely: Android Studio, CLI, and the Agentic Era

Android Studio: Narwhal + I/O Edition

The I/O edition of Android Studio ships a LeakCanary profiler task directly in the IDE. You no longer run LeakCanary as a separate tool — memory leak analysis runs as a first-class profiler task in the same panel as CPU and network profilers.

Agent Mode in Gemini (available in Narwhal Feature Drop and later) handles multi-file tasks: generating tests for a feature, refactoring a module to a new architecture pattern, or migrating from Navigation 2 to Navigation 3. The agent formulates a plan, shows it to you, and executes only after you approve each step.

The iOS app porting feature deserves special attention: you point Android Studio at an Xcode project and an AI agent analyzes the Swift/Objective-C code, maps it to equivalent Android patterns, and generates a working Kotlin/Compose app. Migrations that took weeks now take hours. The output is not perfect, but it produces a running app with the correct architecture patterns.

Android CLI: Your App Is Now Scriptable

Android CLI (adb replacement for semantic operations) is stable and exposes your app to AI agents:

# Semantic symbol resolution — ask Android CLI what a class does
android-cli symbols resolve --class="com.example.HomeViewModel"
# Render a Compose preview to file (for visual regression or AI analysis)
android-cli compose preview --composable="HomeScreen" --output=preview.png
# Analyze a file for warnings without opening the IDE
android-cli analyze --file="app/src/main/java/com/example/HomeScreen.kt"
# Run a specific UI test with Gemini-powered natural-language assertions
android-cli test journey --description="Tap the login button, enter test@example.com and password123, verify the home screen shows"
Enter fullscreen mode Exit fullscreen mode

The test journey command is the most significant: natural-language test assertions backed by Gemini's vision model. You describe the user flow in plain English; the CLI converts it into an automated test that runs against your app. This is how Google intends Android to participate in the agentic development toolchain.

Google AI Studio: Build Android Apps From a Prompt

Google AI Studio now builds native Android apps directly. Select "Build an Android app," describe what you want, and the generated project uses Kotlin, Jetpack Compose, Material 3, and the current NowInAndroid architecture patterns. You can connect your Google Play developer account and publish directly to the Internal Test Track without leaving AI Studio.

This matters for prototyping. The generated code is a starting point, not production code — but it generates the right starting point (Hilt, Room, MVVM, Compose Navigation) rather than the dated patterns that earlier code-generation tools produced.

Android 17: What's Coming and the End of Developer Preview

Android 17 is in its first beta as of Google I/O 2026. Two changes worth knowing now:

The Canary channel replaces quarterly developer previews. Android now ships new APIs and features to the Canary release of Android Studio as soon as they pass internal testing. You no longer wait for a scheduled Developer Preview drop. If you want to build against the latest Android platform APIs, stay on the Canary channel of Android Studio. This is the new normal.

Widgets become Compose-native. Android 17 completes the migration of Jetpack Glance to full RemoteCompose. The legacy RemoteViews approach still works, but Google will point all new widget development at Glance + Compose from Android 17 forward. If you have widgets written with RemoteViews, plan their migration.

Pausable composition is now default. Introduced experimentally in Compose 1.10, pausable composition lets the Compose runtime split long composition work across multiple frames — preventing jank on complex screens. It is enabled by default in Android 17's build of Compose. You do not need to change your code, but you should run your UI tests with the Compose 1.11 v2 testing APIs (see Section 3) to ensure they handle the non-immediate execution correctly.

Your Action Items

A correctly handled edge-to-edge bottom bar: scrim for three-button navigation, transparent for gesture navigation. This is what your app should look like on Android 16.

A correctly handled edge-to-edge bottom bar: scrim for three-button navigation, transparent for gesture navigation. This is what your app should look like on Android 16.

The most urgent changes are in this order:

Ship this week:

  1. Add enableEdgeToEdge() to every Activity and remove all WindowCompat.setDecorFitsSystemWindows calls
  2. Audit every onBackPressed override — migrate to BackHandler or PredictiveBackHandler
  3. Run your Compose tests with Compose 1.11 — any test that fails on StandardTestDispatcher has a hidden timing assumption

Ship this month:

Migrate from Navigation 2 to Navigation 3, Upgrade to Kotlin 2.4 and audit your codebase for context parameter opportunities. Test your app on the Android 16 emulator with gesture navigation enabled.

Plan for next quarter:

Migrate widgets from RemoteViews to Jetpack Glance + RemoteCompose 8. Evaluate CameraX replacement if you use PreviewView in AndroidView Explore Health Connect FHIR if your app touches health data. Enable Android Studio Agent Mode for your most repetitive architectural tasks (generating tests, migrating modules)

What Google I/O 2026 Actually Means

Android in 2026 is not the same platform it was in 2021 when Compose shipped. The ecosystem has converged. Kotlin is the only language. Compose is the only UI toolkit. MVVM with Hilt and Flow is the official architecture. Navigation 3 gives you back-stack as state. The toolchain generates apps that follow these patterns by default.

Five years of investment in Compose is paying off at the platform level: widgets, car displays, Wear OS tiles, and TV all converge on the same Compose model. The XML layout editor, Fragments, ViewPager2 — these are now legacy APIs, maintained but not advanced.

The developers who win in this cycle are the ones who use today's stack to its depth — not the ones who maintain the widest possible backward compatibility. Android 16's mandatory edge-to-edge and killed onBackPressed are not aggressive changes. They are the platform finally enforcing what it recommended for two years.

Your users already expect apps to feel like part of the OS. Now the OS enforces it.

All code in this article targets Android 16 (API 36), Kotlin 2.4, Compose 1.11, Navigation 3, and uses the NowInAndroid architecture patterns with Hilt and StateFlow. The minimum supported SDK in examples is API 24.

Sources

Top comments (0)