What a new publishing format means for the future of Android
Thanks to its openness, Android has seen remarkable growth over its first ten years. There are a huge range of devices to choose from and many apps and games offered by a thriving ecosystem of developers that bring those devices to life. As a developer, you want to ensure that your users have the best experience possible and that your apps run as well as they can on all these devices. You also want to encourage as many users as possible to install your app; you want them to keep using it; and you don’t want them to uninstall for reasons beyond your control. The way Android apps have been published and distributed to date leaves room for improvement in all these areas. I’d like to take a look at some of the challenges developers face and tell you what Google is doing to help.
Android’s first 10 years
For ten years, releasing an app on Android has worked like this:
- Step 1: You write the code for your app in an IDE, such as Android Studio.
- Step 2: When you’re ready to test or release the app, you build it as an APK, Android’s app format. As part of building the APK, you digitally sign it with an app signing key. Signing an app means securely attaching a unique certificate to it. This is a mechanism that ensures you’re the only one who can continue to update installed copies of this app. How does this work? Before updating an app, Android always checks that the unique certificate of the update matches the unique certificate of the app on the device. It will be clear later why I’m spelling this out.
- Step 3: You upload your signed APK to a testing track using the Google Play Console. When you’re ready, you release your app to the production track and to the world.
- Step 4: Google Play distributes your signed APK, precisely as you uploaded it, to each user’s device when they install it.
This has worked pretty well over the years. Indeed, people install over 8 billion apps from Google Play every month! But, as you’ll see, this model presents challenges for developers which are becoming harder to ignore.
The ‘big’ problem
Here’s the problem: apps keep getting bigger and bigger. In fact, since 2012, the average app has grown 5x. This is understandable; you want to add cool features and new content to your app to keep your users coming back and to keep your business growing. Devices keep getting better, and you want to take advantage of the shiny new functions. The device ecosystem has also become more diverse, so you end up duplicating code and resources in your app to make it run just as well on a small screen as it does on a large screen, just as well on one CPU as on another, and so on.
Apps getting bigger wouldn’t matter much if every user had unlimited storage, unlimited data, and ever-present fast connections. Sadly, this isn’t the case (maybe one day!). Looking at the graph below, you can see the size of an app on Google Play is negatively correlated to its install conversion rate. That means that as apps get bigger, their install success rate goes down. This happens for many reasons. Many users don’t have enough free space on their device. This impacts users with entry level devices with modest device storage and users with high end devices who fill their devices with photos, videos, and other media — which all keep getting higher in quality, taking up more space on each device. Users also don’t want to use up expensive data plans and wait on slow connections for larger apps, especially in emerging markets.
So we know the install rate goes down for larger apps. Our user research also shows that app size is also a leading motivator in driving uninstalls, which makes app size an increasingly important factor for apps that are focused on retention. Think about your own experience. When you’ve tried to install an app, have you ever seen a warning from Google Play prompting you to uninstall apps you don’t use to free up space? Millions of people see these warnings every day and they’ll often uninstall the biggest apps and games when presented with this choice. Google Photos ran an amusing advertisement showing how widespread this problem is. In a user research survey conducted by Google Play last year, the leading reason why people uninstalled apps and games that they had for at least a month was to free up space.
I should mention that there is a less than adequate solution to the problem I’ve outlined. Today, you can build and version multiple APKs for each device configuration in a single release. This quickly gets out of hand when you want to optimize for screen sizes, CPU architectures, target both 32-bit and 64-bit, and so on. You can end up building hundreds of APKs for each release. It’s a pain, and most developers don’t do it. Many just put everything in a single, ‘fat’ APK, and users end up with unused, duplicated content on their device. And, even if you use multi-APK, you can’t optimize for languages. You have to include all the translated strings for every device in every APK, even if the user only needs one or two languages, which wastes more space.
So your existing options aren’t great: increase the size of your app but risk lower conversion rates and higher uninstalls, make your releases less efficient and more painful with multi-APK, or spend all of your time weighing up this feature versus that feature in an effort to avoid increasing the size of your app.
The ‘small’ solution
Google doesn’t want developers to have to make these compromises, so we’ve been working on a better way. Here’s the big idea: if you upload everything needed to Google Play, then Play can take care of delivering just what’s needed for each user and device. It’s pretty simple, isn’t it? This process can decrease the work and effort you need to do to support Android’s diverse ecosystem and make your app much smaller for users. As you’ll discover later in the post, this new model also helps improve the user acquisition journey: from discovery and install, to engaging and retaining users with features and updates.
To realize the vision, Google introduced a new app publishing format, the Android App Bundle, earlier this year. Here’s how it works in detail:
- Step 1: You write all your code for your app in an IDE such as Android Studio or a games engine such as Unity as you normally would.
- Step 2: Now, when you’re ready to test or release the app, you build it as an Android App Bundle, Android’s new app publishing format. You still sign the app so that Google Play can verify it’s from you.
- Step 3: If you haven’t already, you opt in to Play App Signing. If you’re releasing a new app, you can do this in a one-click process when you upload your app. When you opt in, Play designates the first key you used to sign your app bundle as the upload key. This is just for security identification purposes and, if you ever lose it, you can contact Google to verify your identity and reset it. For existing apps, you need to visit the app signing page in the Play Console and securely transfer your app signing key to Google Play. Why do you need to do this? Continue to step 4 to find out.
- Step 4: When you upload your app bundle to Google Play, Play processes it and generates split APKs signed with the app signing key for every possible device configuration and language that you support. Split APKs are an Android platform feature introduced in Android L. As long as each split APK is signed with the same key, the Android platform will treat them as one app. You can think of a split APK as ‘part’ of an APK: to run the app, the device treats all the parts as a single app.
- Step 5: When a user installs the app, Play delivers the base split APK (all the code that’s common for every device), the language split APKs (for the languages the user speaks), and the device configuration split APKs (for the device’s screen size and the CPU architecture). This means the device gets just what it needs without wasted space. For updates to be accepted by the device, every release’s split APKs must be signed with the same app signing key as the original app install.
- (Step 6: Once your app is installed on a device, Play will deliver additional split APKs on demand when, for example, a user changes their device language or when a user wants to use a dynamic feature module, I’ll talk about these later in the post.)
This new model results in dramatically smaller apps that take less time to download and less space on a device. You deliver a more efficient app to your users which doesn’t contain code and resources they’re not going to use. It’s also very simple for most developers to switch. Building an app bundle in Android Studio is much the same process as building an APK. Game developers using Unity can also build app bundles in Unity 2018.3, 2017.4, and later. The Android App Bundle is open-source and backwards compatible (for pre-L versions of Android, Play automatically uses multi-APK — that is Play generates an APK for each device configuration, containing all language assets, instead of using split APKs).
We switched to the app bundle and uploaded our first internal release within an hour.
Swiggy ~23% size saving
Thousands of developers of popular apps are using app bundles in production. Developers who are using the Android App Bundle have APK sizes that are on average 35% smaller than releasing a ‘universal APK’ (an APK packed with everything needed to support all device configurations and languages that the Android App Bundle supports). More importantly, for those of you who have to manage each release, the new format means you no longer have to use multi-APK for device configurations. Google Play takes care of this for you and makes your life a little easier. The Play Console will soon start allowing you to upload large app bundles with installed APK sizes of up to 500MB so that, in most cases, you don’t need to use expansion files either. [Edit: Based on feedback during testing of the 500MB limit, we decided to keep the app bundle size limit as 150MB and to introduce a new and more powerful option for large games: the app bundle will now allow asset packs which can be up to multiple GBs. Read more about it here.]
The app bundle saves us time now that we don’t have to use multi-APK.
redBus ~22% size saving
A benefit of the new model and the new publishing format is that Google Play can introduce optimizations into the APK generation process saving you time and effort. An example is something that has just been announced: support for uncompressed native libraries, a little-used platform feature introduced in Android Marshmallow. Developers using the app bundle get this with no extra work.
Prior to Android M, any native libraries included in your app had to be unzipped from the APK. This meant that there were two copies of the library installed on every device: the compressed copy in the APK and the uncompressed copy. That’s wasted space. From Android M onwards, the library can be read directly from the APK in an uncompressed state, thus saving a copy on the device. Play’s compression of the APK during the download is generally more efficient than compressing the native libraries in the APK, so the overall download size is smaller too. So that you can benefit from this without worrying about the upload size, the Play Console’s size limits are changing so that they’re based on the compressed APK size that users download, not the size of the app you upload to the Play Console. On average, this optimization alone is reducing the download size of apps using native libraries by 8% and the installed size on a device by 16%. That’s an amazing size reduction in addition to what you get when switching to the app bundle!
Including assets for 20+ languages was increasing our app size and noticeably reducing our visit-to-install conversion rate before we started using the Android App Bundle.
Riafy ~37% size saving
As I mentioned, apps must opt in to Play App Signing to be able to use the app bundle. App signing keys are a mechanism to ensure updates always come from the same developer after an app is installed. Google doesn’t gain additional access or identifying information about a developer by holding this key. It is used only to sign a split APK for installs and updates. Security is something Google takes very seriously, and Google has a team of engineers and advanced infrastructure protecting developers’ keys using the same secure key storage that Google uses to protect the keys for its apps. In fact, for most developers, opting in to app signing and then using an upload key to sign each release (different to the app signing key held by Google) is more secure than holding the key, which can become lost or compromised. If you’re not opted in and you lose your app signing key, you won’t be able to update your app, and there is unfortunately nothing we can do to help.
The next important innovation in the Android App Bundle is that it’s modular by design. This means you can add modules to your app containing additional app functionality that can be loaded on demand via Play Feature Delivery. This helps with the other big reason for apps getting bigger that I mentioned earlier: feature growth. Now you can add more features and functionality, without increasing the size of your app at the point of install. Play Feature Delivery is a safe way to dynamically load code on Android because dynamic feature modules are scanned and checked in the same way Google Play Protect scans and checks apps themselves.
Any app functionality can be contained in a dynamic feature module and delivered on demand. You code dynamic feature modules in the same way you code your app. The kinds of features that work well include:
- Large features not needed at install: You can load these on demand or tell Google Play to defer installing them, which means installing them in the background. You can load features up to 100MB this way. Advanced features or add-ons that aren’t core to your app experience at launch are good candidates here such as premium features for paying users, personalization options, AR functionality, and so on.
- Features for specific audiences: Instead of including features for every audience using your app, you can carve them out as dynamic feature modules. For example, commerce apps could isolate selling functionality in a dynamic feature module so only the buying functionality gets delivered to every user at the point of install. The small percentage of the audience who need selling functionality can download and access it when they need it. Some developers are also exploring dynamic features as a way to avoid having many variants of an app targeting slightly different audiences. Instead, they can consolidate and offer one app while moving the tailored functionality for each audience into dynamic feature modules.
- Rarely used features: Another good use of dynamic feature modules is for functionality that’s rarely used or used once. For example, if your app has a one-time ID verification or credit card scan, then loading this on demand and uninstalling it immediately after its use is an efficient way to avoid adding to the size of your app at install. It also avoids taking up space for something that’s not being used for the lifetime of your app (remember larger apps are more likely to get uninstalled).
I’ve talked about how the Android App Bundle is helping you keep your apps small and making highly configurable apps possible with dynamic feature modules. The Android App Bundle also supports instant experiences. Google Play Instant lets users try apps and games from the Try Now button on the Play Store, from ads, and from links before installing the full app or game. Instant is now on 1.3B devices and is proving to be a great way to drive discovery and installs, capturing users who may not have otherwise installed an app. Vimeo is one of many partners who have seen success with Google Play Instant, reporting that 15% of their new installs come from their instant experience.
In the past, it hasn’t been easy for some developers to adopt instant apps, because of the independent build and release process. With Android App Bundles, you don’t have to build and maintain a separate instant app anymore. After switching to an app bundle, you can add a module to serve as your instant app’s entry point or, if your app is small enough, you can simply enable your base module to be instant. The size limit for your app’s base module plus the instant app module is 10MB to enable the Try Now button on the Play Store and web banners. Instant apps can only request supported permissions. If your installed app uses other permissions, handle these gracefully in your instant app to ensure a positive experience.
This isn’t to suggest that getting under that 10MB limit is easy for every app. Loading functionality progressively using dynamic feature modules is one of a number of ways to dramatically reduce the size of your app. The size limit only applies when pushing instant-enabled app bundles to production so you can test things out before you’re under the size limit. If you’re able to reduce your base module and instant entry point module even further to under 4MB, you activate more instant surfaces such as Google Search and any web link shared, for example, over email or social media. Building a single app bundle for your instant and installed experience is possible in the Android Studio 3.3 beta release.
The final thing I want to talk about is keeping your users up to date. The last step in engaging and retaining audience is ensuring that they have all your latest features and fixes. While many Google Play users have auto-update turned on, many don’t, and others don’t connect frequently to a strong Wi-Fi connection to keep all of their apps updated. The new Google Play In-app Updates API will let you detect when there’s an update available and integrate a customizable, in-line update flow that looks and feels like part of your app. When an update is detected, you can either notify the user with a prompt asking them to update immediately or show a prompt for a flexible update at a time and in a way of your choosing.
The immediate flow is designed for critical updates, such as security fixes or privacy enhancements, which you want the user to apply as soon as possible. When the user accepts this update in your app, it will be downloaded and applied and the app will be restarted automatically. Some apps implement their own solutions for this today, the new API is an easier, standardized way to do it in your app. Flexible updates are more customizable. When this update is accepted, it will be downloaded in the background. Once it’s downloaded, you can either prompt the user to restart the app or it can be applied when the app goes in the background.
Google Chrome is testing the In-app Updates API today and we’ll be rolling it out to more developers soon. It works for any app so you’ll be able to start using it while you’re still switching to the app bundle. To get a good update rate, it’s best to be clear with the user about the benefit of updating and, when possible, ask them to update after they’ve completed a task, instead of asking when they first open your app. When someone first opens your app, they’re generally doing it for a reason and don’t want to wait around while the app updates.
Smaller, better, faster, fresher
These efforts are about helping you drive more installs and fewer uninstalls with a smaller, more efficient app and a faster, more streamlined release. The Android App Bundle also enables highly configurable apps with dynamic feature modules and instant experiences that can increase conversions. Finally, it’s becoming easier to keep your users’ apps up to date. It’s easy to switch to the Android App Bundle, you can get started at g.co/androidappbundle. Here’s to another 10 years of Android ecosystem growth and developer success.
If you have questions or comments on anything I’ve talked about in the post, tweet at the team using #AskPlayDev and we’ll reply from @GooglePlayDev, where we regularly share news and tips on how to be successful on Google Play.