WebView: A Chromium-Based Component Inside Your App

▶ Watch (1:32)

A WebView is a Chromium rendering engine dropped into an Android app as a native component. It displays web content without leaving the app. WebView runs in its own isolated profile — no cookie jar or local storage shared with Chrome. The app owns the WebView, so native code can communicate with and modify content. To add a WebView in Jetpack Compose, wrap it in an AndroidView, then initialize the engine. Key settings: enable JavaScript (disabled by default), enable DOM storage for session/local storage, and modify the user agent string to serve a desktop version on large screens.

Mixing Native UI Elements with WebView: Tabs

▶ Watch (3:20)

The demo app places a native tab bar above a full-screen WebView. Tabs are implemented with an Android Column: the WebView takes the bottom space, and a LazyRow of material cards sits on top. When a user clicks the create-new-tab button, a separate WebView initializes and is added to a stateful list of TabInstance objects. Each WebView stays active — even when off-screen — so that memory, JavaScript context, and scroll position are preserved. Hidden tabs are moved off-screen using Modifier.offset, not destroyed. This prevents page reloads and state loss.

Two-Way Communication Between WebView and Native Code

▶ Watch (5:09)

WebView evaluateJavascript runs JS from native code. The demo removes a button by executing a DOM manipulation script. The addWebMessageListener function lets JS call native Kotlin code. The web app checks for an object named myNativeReminder; if present, it sends reminder data via postMessage. On the native side, a callback transforms the JSON into a NativeReminder object and passes it to Android’s AlarmManager. The same mechanism can trigger priority notifications, schedule background tasks via WorkManager, or read device sensors — all from the web app’s JavaScript.

Offline Support: Three Approaches for WebView Apps

▶ Watch (7:43)

By default, WebView shows an error page when offline. The demo offers a better experience: a user can create and edit notes without a connection, and changes sync automatically when back online. Three implementation options are shown. First, service workers — supported in WebView — act as a network proxy to intercept requests and cache resources. Second, the shouldInterceptRequest callback lets native code intercept any network request (HTML, CSS, JS, images, API calls) and serve local resources. Third, the simplest approach: detect a load failure via onReceivedError, set an isOffline state, and swap the WebView for a native “no internet” screen with a retry button.

Native Hooks for File Upload and Download

▶ Watch (10:10)

WebView provides hooks to handle native features. For file upload — e.g., clicking the insert photo button — override onShowFileChooser in WebChromeClient. The demo uses the modern Android photo picker, which requires no permission dialogs. The selected image URI is passed back to WebView’s file path callback. For downloads, a setDownloadListener function is called when the website requests a file. The demo passes the URL and MIME type to the native DownloadManager, which shows a notification and saves the file to the default downloads folder. Additional hooks exist for geolocation and permission requests.

Notable Quotes

It’s a seamless way to display web content without requiring your users to leave your app’s context. Sasha Lukin · ▶ Watch (1:45)

If we were to recreate the web view, the page would reload and lose its state. Sasha Lukin · ▶ Watch (4:54)

This is a good example of how you can improve your web experience by adding native Android elements. Sasha Lukin · ▶ Watch (9:59)

Key Takeaways

  • WebView is a Chromium-based component that runs in an isolated profile within an Android app.
  • Mix native UI elements like tabs with WebView while keeping off-screen WebViews alive to preserve state.
  • Use evaluateJavascript and addWebMessageListener for two-way JS-to-Kotlin communication.
  • Handle offline scenarios with service workers, request interception, or a native error screen.
  • Override onShowFileChooser and setDownloadListener to replace WebView defaults with native picker/download manager.