Google Play Asset Delivery in Android
Play Asset Delivery (PAD) is a type of CDN (content delivery Network) service provided by google to host & manage downloading large assets of Games/Apps and that too free of cost.
Why & When It’s Required?
As user experience is improving day by day & resources for apps/games are getting larger in size, APK size is also getting increased.
Google allows Apps/Games to upload Android App Bundle (aab) upto max 150MB.
So What happens when the size of App/Game goes beyond 150MB.?
Here comes the PAD in picture to make things easier for developers.
PAD separates the assets of App/Game, resulting in a smaller AAB size.
By using PAD developers can choose different type of delivery modes, using which assets can be downloaded as per request. We will look in more detail about delivery modes later in this post
What are Benefits of using Play Asset Delivery?
PAD brings the benefits of app bundles to games. It allows games larger than 150MB to replace legacy expansion files (OBBs) by publishing a single artifact to Play containing all the resources the game needs.
PAD offers flexible delivery modes, auto-updates, compression, and delta patching, and is free to use
There are 3 type of delivery modes you can choose:
Lets have look in detail in delivery modes
These asset packs are delivered when the App is installed. They are delivered as split APKs(part of APK set). These packs are installed along with the installing of App/Game. These packs are ready to use as soon as App is launched. These packs contribute to the app size listed on the Google Play Store.
The total download size limit for all
install-time asset packs combined is 1 GB. When the app is updated,
install-time asset packs are updated as part of the base app update (with no action needed from the developer).
These asset packs are downloaded automatically as soon as the app is installed. The user does not have to open the app for
fast-follow downloads to begin.
These downloads do not prevent the user from entering the app. These packs contribute to the app size listed on the Google Play Store. The download size limit for each
fast-follow asset pack is 512 MB.
These asset packs are downloaded while the app is running.
Asset packs configured as
on-demand are served as archive files by the Google Play Store (and not as split APKs). These packs are then expanded in the app’s internal storage.
You can query the location of asset packs served this way using the Play Core API. The app can’t assume the existence of these files or their locations because these files may be deleted by the user.
App updates for
on-demand asset packs follow these steps:
- The patch for the app, including all assets, is downloaded to a secure location on the device.
- The app binary is updated, this includes any
- All previously-downloaded asset packs are invalidated.
- The patch for the assets is copied and applied to assets stored in the app’s internal storage.
In most cases when the user opens the game, the entire update has already completed and the user can start playing the updated version immediately.
In rare cases, when the app is opened, the app binary may have already been updated while the process of applying the patch for the assets has not yet completed and thus assets are not ready to be accessed.
You need to accommodate this scenario by providing an appropriate “Update in progress” user interface element around these assets, or build in logic to deal with invalidated assets that are not ready to be accessed.
Since the app binary update takes place only after all asset pack types have been downloaded, applying the patch is a local, offline action that should complete quickly.
How to Implement Play Asset Delivery?
Requirements : Android Gradle plugin
4.0.0 or later.
In the top-level directory of your project, create a directory for the asset pack. This directory name is used as the asset pack name. Asset pack names must start with a letter and can only contain letters, numbers, and underscores. Check below screen shot for same.
In the asset pack directory, create a build.gradle file & add below code to it.
Now to make our app know about this asset pack, we need to add this to our build.gradle(app) file like shown in below figure. We can add multiple or single asset pack as per requirements.
Also we need to add it to our settings.gradle file too. Here also we can add one or more asset packs as per our requirements. But make sure that asset packs created as directory & included in build.gradle(app) file should be included here & should match the name.
As soon as you are done adding this, hit “Sync Now” button at top right corner in gradle file & wait till build finishes.
After completing above steps now we need to create src/main/assets directory in our asset pack, And add all the assets in this directory. You can create sub-directories as well & place assets in sub-directories. But make sure that while accessing the assets you access like : “subdirectory/asset-name”, otherwise you will end up with File Not Found Exception.
Now the structure would look something like below screenshot.
Now Build the Android App Bundle with Gradle. In the generated app bundle, the root-level directory now includes the following:
/manifest/AndroidManifest.xml: Configures the asset pack’s identifier and delivery mode
/assets/your-asset-directories: Directory that contains all assets delivered as part of the asset pack
Now comes the main part : How to access assets in our java file.?
To access assets first we will need Play Core API in our project. So Lets implement Play core API. To implement play core API via Gradle, add following dependecy in build.gradle(app) file
There are other ways also by which you can implement Play core API, you can find it out here : Link
You implement this API according to the delivery type of the asset pack you wish to access. These steps are shown in the following flowchart
Access assets during Install-time delivery mode. These asset packs are immediately available at app launch.
To get Assets we need to first initialize context & get assets from it. Then we can access assets. So here is the below code for it:
In above code we get the inputStream of the asset that we accessed by passing the asset file name. So now we can use inputStream of the asset & implement it as per requirements.
For example: We can get inputStream of a video file & then create a temp file in external storage, write inputStream to temp file created, & play that video & display that to user.
Access assets during fast-follow & on-demand delivery mode.
To get Assets, first we need to get instance of AssetPackManager. Let look into code :
Now check that fast-follow & on-demand assets are available or not.
As soon as listener is registered & fetch method is called, download of asset pack starts, it can be listened as follows :
On download completion, we receive status AssetPackStatus.COMPLETED and we get path of asset & use it in our app as we want per requirements.
Here is the implementation of getPackStates method :
Here is the implementation of showWifiConfirmationDialog method:
Here is the implementation of getAbsoluteAssetPath method :
At the end do not forget to unregister the listener we registered
So guys this was the implementation part. We have implemented the code for how we can access the Assets by separating it from our app & extracting it to asset-packs.
So when we generate Android App bundle, root directory will contain our All app related project files & our Asset-pack. And we just need to upload the bundle(aab) file to google play console & rest will be taken care by Google.
But before uploading it to Play console, we first need to Test it. Here comes most important part of our development, that is Testing.
How to Test Play Asset Delivery?
To test Asset Delivery follow the below steps:
1. Build Android App Bundle, for more details Link
2. Generate APKs with –local-testing flag as below, In Android studio Terminal hit below command :
3. Connect a Physical-device/Emulator to Android Studio, & hit below command to install generated APKs
Wait for the process to finish, once the app is installed you can test it by playing a audio/video file or by accessing a image from asset-pack & displaying it on the screen or by implementing it as per your requirements.
But please take care of following limitations while testing in local
- Packs fetch from external storage instead of Play, so you cannot test how your code behaves in the case of network errors.
- Local testing does not cover the wait-for-Wi-Fi scenario.
- Updates are not supported. Before installing a new version of your build, manually uninstall the previous version.
To overcome this limitations you can test with internal app sharing facility provided by Google.
To test Asset Delivery using internal app sharing, do the following:
- Build your app bundle.
- Follow the Play Console instructions on how to share your app internally.
- On the test device, click the internal app-sharing link for the version of your app you just uploaded.
- Install the app from the Google Play Store page you see after clicking the link.
If you do not have bundletool.jar, you can download it from here : Bundle tool download link
You can see sample app for more details.
So this was all for Play Asset Delivery. Hope you guys liked it & understood how Play asset Delivery works. Claps would be appreciated. Stay tuned for more such blogs.