What is an instant app?
A Google Android instant app is a small software program that enables end-users to test out a portion of a native Android app without installing it on a device. Instant apps, although they run like local apps, are native containers with access to a device’s hardware. Because end users do not install them, instant apps do not take up storage on the device.
Why do we need an instant app?
One of the main benefits of instant apps is discoverability. App developers often struggle to increase the visibility of an app because it is buried within the app store. With instant apps, a Google search or company website can lead the end-user to an instant app.
Instant apps require less hassle on an end user’s part, which may decrease the likelihood of a user leaving a negative review if he is dissatisfied.
Android instant apps are particularly powerful for e-commerce organizations and game developers. Game developers, in general, can benefit from instant apps because end users can play a particular level of the game. Once that level piques the end user’s interest, he or she can download the full app.
Developing an instant app-
Modularize and refactor your application
To add support of the instant run feature, developers need to modify their project structure. This is because the vast majority of apps today are mostly single module builds while supporting Instant Apps requires to split builds into multiple modules called features.
Each feature represents a part of the application that can be downloaded on demand.
Below image represents the simple application structure for Instant App:
-
Base feature module
The base feature module can be thought of as the root of your project. It contains the shared code and resources to be used by other modules. The base feature differentiates itself from other features with the property base feature set to true.
apply plugin: "com.android.feature" android { baseFeature true ... } dependencies { feature project(“:feature”) application project(“:app”) ... }
-
Feature modules
These are modules that apply the new android. feature Gradle plugin. They are simply library projects, producing an AAR when consumed by other modules. It’s worth noting that they do not have application IDs because they are just library projects.
apply plugin: 'com.android.feature' android { ... } dependencies { implementation project(':base') ... }
-
APK module
This is the normal build module that we are all familiar with. Now it’s set up to consume the base and feature modules in order to output an apk to be installed on user devices. Since it aims to output an installable artifact this module does have an application ID.
apply plugin: 'com.android.application' android { defaultConfig { applicationId "com.example.instantappsdemo" ... } ... } dependencies { implementation project(":my-base-feature") implementation project(":my-feature") }
-
Instant App module
Implements the com.android.instant plugin. The consume feature modules and produce a split APK zip containing all of the features that will go into the Instant App. It’s pretty much an empty shell of a project without a manifest that only implements other features feature modules in the project.
apply plugin: "com.android.instantapp" dependencies { implementation project(":my-base-feature") implementation project(":my-feature") }
Support deep linking and App links
If you have built complex apps that support multiple users flows, you will likely have implemented deep linking. Deep linking allows anyone to create a URL that links directly into a particular screen or flow in your app. Since Instant Apps run on URLs, deep links and app links are now a requirement. One major difference between regular deep links is that custom URI schemes are not supported.
Every feature in your Instant App must have at least one entry point that is defined as a deep link. This defines what Activity users will see when they click an Instant App URL, or if they navigate to the feature from a different feature in your Instant App. Here is an example of an intent filter that binds a deep link pattern to an Activity.
<activity android:name=".InstantDemoActivity"> <intent-filter android:autoVerify="true" android:order="1"> <action android:name="android.intent.action.VIEW"/> <category android:name="android.intent.category.BROWSABLE"/> <category android:name="android.intent.category.DEFAULT"/> <data android:host="example.com"/> <data android:pathPattern="/instantadplay/.*"/> <data android:scheme="https"/> <data android:scheme="http"/> </intent-filter> </activity>
App Links
You will also need to associate your web domain with your Instant App’s package name. This binding, known as Android App Links, proves to Google that you own and control the web domain that you wish to associate with your app.
Now, by setting up App Links for your Instant App, users without your installed app will be routed seamlessly to your Instant App.
However, App Links is a requirement for Instant Apps to work. To set it up, you simply need to host a single JSON file on the root of your domain or subdomain at <my-domain>/.well-known/assetlinks.json
[ { "relation": [ "delegate_permission/common.handle_all_urls" ], "target": { "namespace": "android_app", "package_name": "com.myapp.packagename", "sha256_cert_fingerprints": [ "96:14:26:30:CC:E3:C0:9B:05:12:7B:9A:31:9E:88:36:82:12:84:27:4C:52:2F:05:FE:66:A8:AB:B9:F0:F5:F0" ] } } ]
- Each feature of your Instant App must be under 4MB in size.
- Every project that uses feature modules must have exactly one base module and every feature module must depend on the base module.
Actual implementation in our SampleApp Project.
Below are the screenshots of the project structure and each module structure we kept for this Test app.
-
SampleApp Project Structure:
- Installed Module / APK Module: This module is containing the main app source code.
- Base Feature Module: In our case, this module doesn’t contains code part or common source code part.
- Feature Module: In our case, this module contains code part which is running for the instant run or if the user clicked on the “try now” button from play store.
- Instant app Module: The feature module defined in its build .gradle file will work for the instant run feature. This module doesn’t have the code part and AndroidManifest.xml file.
While the roll out you will get some errors, so, Please consider below solutions for the errors.
Error
- Your site ‘www.mywebsitename.com’ has not been linked through the Digital Assets Link protocol to your app. Please link your site through the Digital Assets Link protocol to your app.
Solution
- Please check whether Google Play App Signing is enabled on Google Play Console. If Google Play App Signing is enabled, Google Play Console will replace your app key with a release key. And the key you set on Android Studio is treated as upload key. So, you need to modify your JSON with the release key.
Error
- You should have at least one active APK / installed app that is mapped to site ‘www.mywebsitename.com’ via a web ‘intent-filter’.
Solution
- Upload installable APK with same HOST web ‘intent-filter’. : Your apps main activity should be mapped with web intent-filter same as instant app module activity web intent-filter.
Error
- Some users of this Instant App APKs will not be eligible for any of the APKs in your installed app.
Solution
- Ensure that the targeting of your Instant App APKs matches the targeting of your APKs. : keep the targetSdkVersion same as your previously released APK and Keep the targetSdkVersion same for all the modules.
Error
- All of your APPs require the following device features: android.hardware.camera, android.hardware.screen.portrait, and android.hardware.location
Solution
- Add below lines in your installed module AndroidManifest.xml file
<uses-feature android:name="android.hardware.screen.portrait" android:required="false" /> <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" android:required="false"/> <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" android:required="false"/> <uses-permission android:name="android.permission.CAMERA" android:required="false"/> <uses-permission android:name="android.permission.VIBRATE" android:required="false"/>