Instant apps are a great way to introduce users to native apps experience without the need of installation. App fragments called features can be downloaded quickly thanks to their size limitation (4MB). This brings great user experience to people who can't afford to install a whole application or don't want to download the whole app for one functionality. Simply assign app links to your feature modules. Now whenever a user clicks a link present in your Instant App schemas, and your app is verified, instead of opening the browser, the Play Store will download your feature, cache it and launch a portion of your native app.

Requirements and limitations

Instant apps came with a couple of new features, requirements and limitations.

Instant Apps Requirements:

Before you can start developing your first instant app, you will need to meet a few requirements:

minSdk 21

Android Studio 3.0 +

Android SDK Build-Tools 26.x or higher

Instant Apps Development SDK (latest)

Instant Apps limitations:

As I mentioned before Instant Apps came with a few limitations. You need to remember that the communication with API must be done over https. Your app won't be able to use background services, send background notifications or access unique device identifiers.

The list of permissions for Instant Apps also got reduced, here are all of them:

BILLING

ACCESS_COARSE_LOCATION

ACCESS_FINE_LOCATION

ACCESS_NETWORK_STATE

CAMERA

INSTANT_APP_FOREGROUND_SERVICE only in Android 8.0.

INTERNET

READ_PHONE_NUMBERS. This permission is available only in Android 8.0 (API level 26).

RECORD_AUDIO

VIBRATE

Creating your first instant app

Building your Instant App from scratch is very easy. But before you start, I would recommend you to spend some time thinking about how your project should look, what features it will have and what codebase/resources/dependencies it will share. It will come in handy later. Now let us jump into creating our first Instant App.

When creating a new project remember to select API 21 or higher, also make sure the "Include Android Instant App support" checkbox is selected.

You can now specify your first feature module name. Alongside Android Studio will create modules

"app" - responsible for generating installable apk

"base" - shared module between all features

"instantapp" - generates instant app zip bundle with all feature modules apks

When adding a new activity to feature module you will be asked to specify the app link. The intent filter will be created only with https scheme so I would recommend you to go to manifest file and also include http.

After the last step, you should have generated four modules. Now let us take a closer look at each of them.

app (gradle plugin: apply plugin: 'com.android.application')

apply plugin: 'com.android.application' android { ... defaultConfig { applicationId "com.example.android.myapplication.app" ... } ... } dependencies { implementation project(':feature') implementation project(':base') }

Its main purpose is to merge all modules into installable apk. If your installable app won't differ from instant app this module will be left as it is. Just remember to add every new feature as dependency.

instantapp (gradle plugin: apply plugin: 'com.android.instantapp')

apply plugin: 'com.android.instantapp' dependencies { implementation project(':feature') implementation project(':base') }

Just add dependencies for all the features that you want to end up having in your final instant app zip file. You can also add build types and flavours here.

base (gradle plugin: apply plugin: 'com.android.feature')

apply plugin: 'com.android.feature' android { compileSdkVersion 28 baseFeature true defaultConfig { minSdkVersion 21 targetSdkVersion 28 versionCode 1 versionName "1.0" } ... } dependencies { api 'com.android.support:appcompat-v7:28.0.0-rc01' api 'com.android.support.constraint:constraint-layout:1.1.2' application project(':app') feature project(':feature') }

Here we have some new things: baseFeature true. This settings tell gradle that all of the rest features will get their shared code and resources from this feature. We don't need to specify application id for instantapp module thanks to base features application project(':app') declaration. A base will fetch everything it needs from our installable module. Remember to also include all feature modules here. While adding code, dependencies and resources to base module remember that both, your base and feature, can't exceed the 4MB limit set for today's Instant Apps.

feature (gradle plugin: apply plugin: 'com.android.feature')

apply plugin: 'com.android.feature' apply plugin: 'kotlin-android' apply plugin: 'kotlin-android-extensions' android { ... } dependencies { implementation fileTree(dir: 'libs', include: ['*.jar']) implementation"org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" implementation project(':base') ... }

As you can see a feature module differs from your installable module by not implementing all features, also we don't need to specify application id thanks to a base feature dependency.

And here you have your first hello world instant app. Now go ahead and add some new features through File/New/New Module/Feature Module

Just remember that from now on you will need to start your activities like this:

val intent = Intent(Intent.ACTION_VIEW, Uri.parse("https://android.example.com/character") startActivity(intent)

App links made easy (Tools/App Links Assistant)

App Links Assistant is a useful tool for managing your app links. Let me mention some of its features

URL Mapping

To access this functionality you need to open the Url Mapping Editor and in the URL Mapping table press "+". With this tool, you can easily map your activities to your desired links. If you want to use this tool you have to remember about putting different <data/> in different <intent-filter> blocks or else this tool will have some problems to distinguish each URL Mapping. The reformatting option works really poorly so I would recommend doing it manually or just don't use this tool at all.

After editing proper filters will be added in AndroidManifest files

<intent-filter>

<action android:name="android.intent.action.VIEW" />



<category android:name="android.intent.category.DEFAULT" />

<category android:name="android.intent.category.BROWSABLE" />



<data

android:scheme="https"

android:host="android.example.com"

android:pathPattern="/character" />

</intent-filter>

Remember to always duplicate this filter with http scheme

Associate website

For be able to upload your instant app zip bundle to Play Store your app links need to be verified. In order to do it, you need to add Digital Asset Links json file to your website known location ({site_domain}/.well-known/assetlinks.json). With this tool all you have to do is specify your app id and site domain, also if you want to use Smart Lock API you should check Support sharing credentials... and add sign in URL or mark checkbox if it's the same as the domain. Hit generate button and you are ready to download/copy and paste the assetlinks.json file.

More info: https://developer.android.com/training/app-links/verify-site-associations

Run your Instant App

There are a couple of ways you can run your instant app.

Custom Builds

As you can see you need to change Launch from Default Activity to URL and specify your desired URL. Don’t worry, Android Studio won't allow you to create a configuration with a wrong URL because it will scan your AndroidManifest files before accepting.

Launch features from ADB when your instant app is on device

If you want to launch a specific feature you can use this ADB command:

adb shell am start -a android.intent.action.VIEW -d “{url}”

Test App Links

Go to App Links Assistant and select last option Test App Links. From here you can choose from which module your app should run installed/instant app, and add the desired URL. If Android Studio won't find associated <inetnt-filter> with URL you won't be able to launch run.

Try now button

After successfully adding the app links to all of your activities now is the time to decide which one of them will be your instant app default activity and the one that the Try now Play Store's button will launch. To do so you need to add the <meta-data/> block to that activity

<meta-data

android:name="default-url"

android:value="https://android.example.com/character" />



Some more about space requirements

We already know how important is the size of your features so I would like to share some great tips for reducing your apks sizes:







use WebP for images

remove unused code

try to find lighter weight libraries for an instant app and use inheritance and composition for swapping them for desired ones in installed version

use Refactor/Remove Unused Resources...

use splits in your gradle to split resources into different apks

android { ... splits { generatePureSplits true density {enable true } } }

As I told you before the instant apps base feature and any other feature combined can't exceed 4 MB size limit. It doesn't mean your whole app can't be as big as you want. All you have to remember about is to stick with the 4 MB rule. For example, if your base feature size is 2 MB then all your features must take less than 2MB. Your features size will be checked while uploading your instant app to Play Store.

Google recently launched 10 MB program for Instant Apps. If you want to participate all you have to do is fill this form.

Handling proguard in Instant App

With instant apps, you will probably need at less two proguard rules files. One for the installable version of your app and another one for your base feature module. At first, create rules for your installable version and add it to a module with apply plugin: 'com.android.application'. Now in features, proguard gets a little bit tricky because your application won't be built into one big apk file. Every module will be built separately and later packed into one zip file. So your base feature doesn't know that one of your features uses one of its util classes, you need to tell proguard to keep thus classes separately. Little word processing and usage of apkanalzyer will be useful for this. Build your app with any variant that has

minifyEnabled set to false. Now for all your features apks that are located in their build folders run the command:

$ comm -23 <(~/Library/Android/sdk/tools/bin/apkanalyzer dex packages detail-debug.apk | grep "^C r" | cut -f4 | sort) <(jar tf ~/Android/Sdk/platforms/android-xx/android.jar | sed s/.class$// | sed -e s-/-.-g | sort)

This commandline will produce the list of classes that you must add as keep rules to proguard file for your feature modules.

More info

https://medium.com/google-developers/enabling-proguard-in-an-android-instant-app-fbd4fc014518

Some general tips

The base feature module does not automatically add koltin dependencies and plugins even when you select kotlin support while creating the project

Remember to remove the application from a device before switching from testing between an instant app and an installed app, not doing this results in runtime crashes

Despite the strict permissions, you can still access internal storage

Instant apps have access to Cookie API so it is wise to use it to transfer some user data from instant to the installed application.

To ensure every application launches an instant app from your URL use Firebase Dynamic Links :

Google recommended way of authorization user, is to use AUTH service

With Instant App API , you get access to a couple of useful features.

PackageManagerCompat - allows you to use cookie API on devices with API < 26



I nstantApps.showInstallPrompt - shows full app version installation dialog in your app, it is recommended to have at less one button with installation prompt bound into it



From the PackageManager, the isInstantApp() function tells you if a user uses an application as Instant App or fully installed. Call it before showing the install prompt

Summary

Overall I think Instant Apps will bring benefits to your users and your team. From a user perspective, you get a fast native experience without the need of installation. Users will be able to jump right into your app from links sent to them by friends. As for your team, you have all the benefits from modularizing your project, easy to refactor or completely change features each in its own module. Project maintenance will also be easy with well-planned structure.

There are also some disadvantages. You need to remember that you have limited permission usability. So, if your feature uses NFC you can forget about including it to your Instant App. Some of the background processes are limited. Don't forget about size limitations, support libs weight 2MB alone, so without Proguard, you won't be able to ship your Instant App. Thanks to the way of building Instant Apps, Zip Bundle Proguard doesn't work like in an installable apk and you need to make more effort to work it out. Overall I would highly recommend trying out instant apps.