Over a year ago, Google introduced Instant Apps as a way to make installing Android apps frictionless. With traditional apps, a user has to visit the Google Play store, find the app he or she is interested in, accept the required permissions, install it and launch it. With Instant Apps, the user can just browse through web pages, and land in an app without even noticing. The Android runtime downloads and launches the Instant App transparently. The user experience is much smoother. Companies have started creating Instant Apps and report markedly greater engagement and conversion rates.

On the development side, creating Instant Apps does require a significant effort that is far from instantaneous. The developer typically needs to convert a traditional installed app into an Instant App, by manually refactoring and partitioning the code base. Early adopters report 4 to 6 weeks per app to convert traditional apps.

This article is a summary of our presentation at Droidcon SF 2017. In the article, we discuss Instant Apps, the traditional conversion process and the alternative automated approach that we have implemented in DexGuard. It represents a huge technological improvement, reducing the conversion process from weeks to minutes.

Instant Apps



Traditional installed apps have a code base with a manifest, code, resources and assets, all packaged in a monolithic application. The developer uploads the application to the Google Play store. The user downloads and launches the application.

Instant Apps introduce the concept of features. They partition the functionality into smaller components.

Each feature is an independent collection of code, resources and assets, necessary for one or more activities. Typical activities are a welcome screen, a product page, a shopping cart screen or a high score table. Each activity has its own URL. The developer uploads the set of features to the Google Play store. The user can now navigate from a web page to an activity, and from the activity to other activities. The Android device and the Google Play store transparently download the necessary features in the background.

Technically, features may not depend on each other, but they can share some code, resources and assets. This shared code base is packaged in a base feature.

More concretely, this structure of features exists at two levels:

An Instant App project in Android Studio has modules that correspond to the features. Each of the modules contains a manifest, code, resources and assets. The developer is responsible for maintaining this structure.

The resulting output also reflects the structure. Each feature, including the base feature, corresponds to a separate apk file. Each apk file has a compiled manifest, code, resources and assets.

Constraints



Google imposes some artificial constraints on Instant Apps, enforced through the Android Play store:

For reasons of security, the apps can only use a limited set of permissions, as documented in the manual. Users need to opt in to Instant Apps, but given how easily accessible they are, it's better to protect users from apps applying their power in unexpected ways. The app needs to request its permissions dynamically.

For reasons of efficiency, the apps can have a maximum size of 4 MB. The size is counted as the sum of the size of the base apk and the size of the largest feature apk. A size of 4 MB isn't much by modern standards, so minimizing the app size and effectively partitioning it in any number of features is vital.

Creating an Instant App, the traditional way



When you create a new project in Android Studio, you can tick the check box to create an Instant App project. The wizard then creates a project with the necessary modules for one or more features. Each module is set up with a Gradle build file and an Android manifest with the proper elements and tags. You can then create an installed app and an Instant App.

If you convert an existing traditional project to an Instant App project, you need to create the feature modules yourself. Android Studio can help with a number of wizards, to extract code and resources into separate features.

Revisiting the conversion process



A typical Android app contains many elements: the Android manifest, classes written in Java or Kotlin, resources, resource files, asset files and optionally native libraries. This diagram shows how these elements can depend on each other: classes can refer to resources, resources can refer to resource files, resource files like layouts can again refer to classes, etc. The diagram shows just a few elements, but an actual application easily contains hundreds or thousands of them.

You can now consider the activities in the application as the main entry points. If you want to know which other elements are required for running a given activity, a dependence analysis can provide the answer. The set of transitive dependencies is the code base that is potentially necessary at runtime.

ProGuard and DexGuard already perform such analyses to determine which code and resources they need to keep, and which code and resources they can remove from the application. If you apply such an analysis to each of the activities, you can create a Venn diagram of elements that shows their dependencies.

If you're interested in creating an Instant App, the diagram immediately clarifies which elements can go into the feature modules/apks and which shared elements need to go into the base module/apk.

This is the process that you also apply mentally when you try to tear feature modules apart in your project, albeit probably not at such a level of detail. The process is pretty well-defined though, so why not automate it? This is exactly what we have done. Harnessing the sophisticated analysis and processing of DexGuard, we can now refactor and partition a traditional project or apk into an Instant App (*).

Since DexGuard performs the conversion in every build, it is optimal for each version of the app. It is able to split the entire code base, including libraries, which are monolithic in Android Studio.

Creating an Instant App, the fast way



Practically, we simply need to add a few lines of configuration to the existing ProGuard/DexGuard configuration file. With a single option, we can specify a feature name, an activity name and its corresponding URL. For example:

DexGuard then fully automatically refactors, shrinks, optimizes, obfuscates and partitions the code and resources. The output is a set of individual Instant App feature apk files.

Given these simple settings, experimenting also becomes a lot easier. What if you make changes to the code? What if you add a feature? What if you combine multiple activities in a single feature? Quick builds provide all the answers.

We've applied DexGuard's automated conversion to 25 open-source apps, from Firefox over IOsched to Frozen Bubble - way more than we'd ever want to endeavor manually. Although some sample apps are simply too large to fit in the 4 MB limit, and some sample apps require permissions outside the allowed set, the process minimizes the amount of work needed to pick and choose functionality, and create proper Instant Apps.

Conclusions



Creating an Instant App is a non-trivial and time-consuming process. The developer needs to refactor the application code and resources, and most importantly partition them into independent features. DexGuard automates the entire process, reducing the conversion time from 4 weeks to 4 minutes. The process is easier to set up, easier to maintain, more flexible and it provides optimal results in every build.

(* patent pending)