Technical
Using Google Play Asset Delivery with Android TWAs
November 4, 2026 · 7 min read
When packaging a web-based game, 3D visualiser, or media-rich interactive application into an Android app, developers often face storage limitations. Standard Progressive Web Apps rely heavily on browser storage mechanisms like Cache Storage and IndexedDB. However, Android browsers impose storage quotas, and service worker caches can be evicted under low-disk scenarios.
For applications exceeding 100MB, relying solely on network fetches and browser caching introduces significant performance bottlenecks. Google Play Asset Delivery (PAD) offers a native solution, allowing developers to package up to 2GB of game assets directly within the Android App Bundle (AAB). This guide explains how to integrate Google Play Asset Delivery inside a Trusted Web Activity (TWA) to serve heavy web assets locally and offline.
Why Use Play Asset Delivery inside a TWA?
A standard TWA loads your web application from a secure, verified URL. If your application relies on high-resolution graphics, 3D models (such as GLTF or OBJ files), or long audio clips, downloading these assets on every initial launch degrades the user experience. By leveraging Google Play Asset Delivery, you can bundle these large assets inside your AAB wrapper, offering several benefits:
- Reduced Bandwidth: Assets are downloaded directly from Google Play servers when the app is installed or updated, saving your web hosting bandwidth.
- Instant Load Times: Heavy media assets are accessed directly from the local device storage, eliminating initial loading screens.
- Offline Resilience: Even if the user has no active internet connection, local assets are immediately available to the web environment.
- No Eviction Risks: Unlike browser caches, assets delivered via PAD are never evicted by the operating system during disk cleanup tasks.
Understanding Asset Delivery Types
Google Play Asset Delivery offers three distinct delivery modes. Choosing the right mode depends on how soon your TWA requires the files after installation:
| Delivery Mode | Download Phase | Usage Scenario in TWAs |
|---|---|---|
install-time | Downloaded during app installation. Included in the initial app size. | Critical assets, core shell layout, local WebGL engine components, and primary UI graphics. |
fast-follow | Downloaded immediately after installation completes, in the background. | Secondary game levels, high-definition textures, or optional media expansions. |
on-demand | Downloaded only when explicitly requested by the web application. | Highly specific localized assets, optional audio tracks, or custom level packs. |
For most TWA wrappers, the install-time delivery mode is the most efficient, as it ensures all necessary local resources are present on the storage medium immediately upon the user's first click.
Mapping Local Assets to the Web Context
The primary technical challenge is bridging the gap between the native Android storage where PAD files reside and the web context of your TWA. Because a TWA is executing within a secure web container, it cannot directly query the local Android file system using conventional file:// paths due to security restrictions.
To overcome this, you must use WebViewAssetLoader inside your native TWA wrapper. This API maps your locally stored asset pack directory to a virtual URL matching your verified web origin. When your PWA requests a file from this virtual path, the TWA intercepts the request locally and serves the file directly from the asset pack instead of hitting the network.
For example, if your verified domain is https://example.com, you can configure your native project to map https://example.com/assets/ directly to your local PAD asset directory. Any network request made by your service worker or HTML layout to that path will bypass the internet completely.
Configuring the Asset Pack in Your Project
To implement this setup, you must declare an asset pack module in your Android project. An asset pack is structured as a separate directory within your Gradle project layout. You create a folder named asset-pack-name and configure its build.gradle file to specify the delivery mode:
apply plugin: 'com.android.asset-pack' assetPack { packName = "gameassets" feedbackMode = "completed" }
Inside this asset pack module, place your media files within the required directory tree: src/main/assets/. When Gradle compiles your project into an AAB, these files are bundled into an independent asset pack that Google Play handles during installation.
Setting Up WebViewAssetLoader for TWAs
To configure your TWA to intercept web requests and fetch from your local asset pack, you must override the request interception logic within your custom TwaClient or custom helper class. This is achieved by registering an instance of WebViewAssetLoader with a path handler:
final WebViewAssetLoader assetLoader = new WebViewAssetLoader.Builder() .setDomain("example.com") .addPathHandler("/assets/", new WebViewAssetLoader.InternalStoragePathHandler(context, assetPackDirectory)) .build();
When your TWA web code triggers a request (e.g., using the fetch API), you intercept the URL. If it falls within the /assets/ route, pass the URI to the asset loader. The loader parses the matching local files from the gameassets directory and feeds them back as standard web responses, maintaining absolute protocol and origin security.
Checking and Fetching Assets in JavaScript
For on-demand asset packs, your web application must communicate with your native wrapper to request and monitor the download status of the pack. This requires establishing a web-to-native communication channel, often using custom deep links or query parameters parsed on app launch.
When the PWA requests an on-demand asset pack, the native wrapper calls the Google Play Core API to initiate the download. While downloading, the wrapper can pass progress percentages back to the web UI by updating the query parameters or triggering a custom message. Once the status transitions to completed, your PWA can safely request the assets through your mapped virtual directory path.
By implementing this architecture, large web apps and HTML5 games can run with native-level performance, enjoying the benefits of Google Play's delivery infrastructure while maintaining the flexibility of a modern Progressive Web App.
Ready to ship your Android app?
Paste your PWA URL, get a signed APK and a Google Play ready AAB in minutes.
Build my app