Insights to help you create apps which work on Android phones around the world
Android (Go edition) was announced at last year’s Google I/O, with a goal to bring high-quality smartphone experiences to entry-level devices across the globe. Earlier this year, 6 OEMs announced their devices at Mobile World Congress, and many more OEMs are committed to building new Android (Go edition) devices in the future. We’re really excited about this momentum, and we encourage you to go out and buy your very own Android (Go edition) device from one of our partners!
Our OEM partners have been hard at work to get devices to market, and we are starting to see these devices become available to users. In parallel, I’ve been working with the Google Play team to collaborate with the Android developer community to ensure that developers are optimizing their app experiences for these devices where appropriate. In this post, I will share our partners’ work to optimize their apps and games for Android (Go edition).
Understanding the opportunity
As discussed during our Google I/O session, Android (Go edition) is designed to improve the experiences on entry-level devices (devices with <1GB of RAM). Users around the world have struggled with battery issues, a lack of storage on device, data constraints and poor processor speeds, which created churn and dissatisfaction with their phones. While Google has done a lot of work to optimize our apps, like Search, the Assistant, Maps and YouTube, it is also important that app and game developers ensure their offerings work well on these devices, so that users have a premium experience at an entry-level price point.
The requirements we outlined for Android (Go edition) are meant to help you deliver a great experience for users on entry-level devices. And as you will see, many of the optimizations you apply will actually benefit all of your users across all devices, globally, with a smaller app that is more performant.
To optimize, or to start fresh? Choose your app strategy
The first question many of you ask yourselves is: “Should I optimize my existing app or build a new one?” While the question is deceptively simple, the answer can be a little more complex. It also depends on factors such as how much development resources you have; whether or not you can keep features in your app that are optimized for these devices; and what type of distribution scenarios you want to enable to end-users around the world.
There are three scenarios that can be identified:
- One app for all. Use the same app for Android (Go edition) devices and all other devices with an identical experience. In this case, you are optimizing your existing app to run well on these devices, and your existing users gain performance benefits from those optimizations. This app may be multi-binary, but does not have a specific experience for low ram devices. We highly encourage you to use the new Android App Bundleto experience up to 65% in size savings, without having to refactor your code.
- One app, different APKs. Use the same app for Android (Go edition) devices and all other devices, but different experiences. Create different APKs; one APK to target the new android.hardware.ram.low dimension vs APK(s) targeting all other devices.
- Two apps. Create a new “lite” app and target Android (Go edition) devices. You can leave your existing app as is. The “lite” app can still target all devices in all locales as there is no requirement for this “lite” app to only target Android (Go edition) devices.
There are pros and cons to each of these, and it would be best to evaluate all of these scenarios against your particular business goals.
Tips for optimizing your app
Once you’ve decided on an app strategy, there are some key considerations when it comes to optimizing your app for these devices:
- Making sure your app functions without ANRs and crashes
- Targeting Android Oreo
- Keeping your installed size below 40MB for apps, and 65MB for games
- Keeping PSS under 50MB for apps, and 150MB for games
- Keeping your app or game’s cold start time under 5 seconds
Let’s dive into each of these performance indicators with examples from existing Android developers.
Make sure your app functions without ANRs and crashes
Studies have shown that ANR (application not responding) errors and crashes can have a significant negative effect on user retention and can lead to high uninstall rates. While some of the consumers buying Android (Go edition) phones will be buying their first smartphone, they will expect a zippy, clean, and efficient experience that doesn’t freeze up their phone. Android vitals in the Google Play Console, allows you to track ANRs and crashes, as well as dive deep on bugs that are affecting certain users or types of devices. The tool has been indispensable for many of our developers in identifying, triaging and fixing issues that come up with their apps.
“For crash rate and ANR reduction, we use Android vitals and Crashlytics by Firebase for active monitoring and have managed to operate at ~99.9% crash free sessions and ANR rate of <0.1%, thus bringing down our crashes by 10 times as compared to our earlier versions,” says Arindam Mukherjee, Senior Director, User Experience & Growth at Flipkart. “In order to achieve this, we have followed a phased rollout of our app — monitoring for crashes and ANRs, extensively using Nullity Annotations to figure out NullPointerException issues when running the static code analysis tool. We also do the testing on the ProGuard enabled release build, which helps us catch the obfuscation related issues early in the cycle.”
There are some common patterns to look for when diagnosing ANRs:
- The app is doing slow operations involving I/O on the main thread.
- The app is doing a long calculation on the main thread.
- The main thread is doing a synchronous binder call to another process, and that other process is taking a long time to return.
- The main thread is blocked waiting for a synchronized block for a long operation that is happening on another thread.
- The main thread is in a deadlock with another thread, either in your process or via a binder call. The main thread is not just waiting for a long operation to finish, but is in a deadlock situation. For more information, see Deadlock.
Target Android Oreo
Android Oreo (target API 26) includes a lot of resource optimizations such as Background Execution Limits, which ensures that processes run properly in the background while keeping the phone operating smoothly. Many of these features were specifically designed to improve battery life and overall phone performance, and are key to ensuring that those using these devices will have a great experience with your app. I highly recommend you read through the migration guide put together by Google Play if your app or game is still not targeting API 26 or above. In particular, pay close attention to background execution limits and notification channels. Remember that there have been security updates announced: new apps published to the Play Console will need to target at least API 26 (Android 8.0) or higher by August 1, 2018, while updates to existing/published apps will need to do so by November 1, 2018. To comply with these requirements, you’ll need to target Oreo as soon as possible.
Keep installed size small
There is a very clear correlation between APK size and install rates: the lower your APK size, the higher your installs. People on Android (Go edition) devices will be very sensitive to on disk size, as these phones generally have limited storage capacity. That is one of the reasons why the Play Store will display app size over app rating in certain situations like search results and Play Store listings. While the Play Store on Android (Go edition) devices is the same Google Play Store that is available to users on all devices all around the world, we are customizing the Store experience where we feel it is important to users on these devices.
“A key focus for our Android team has been to have empathy for users working with constricted network and device resources,” says AJ Cihla, Head of International Growth at Tinder. “Even better, with the launch of the Android App Bundle, we were able to trim down another 20% and do so in a simple, sustainable way that naturally fits into our continuous integration and deployment pipeline. All in all, we are looking at a 27MB APK for Android Go devices; a massive leap forward from the 90MB+ package we were distributing this time last year.”
Because of capacity constraints on these devices, it’s best to keep your app under 40MB and your game under 65MB. Many Google Play developers found this to be a key reason as to why they decided to either optimize their existing APK, or build a separate APK that is targeted to Android (Go edition) devices. Here are some suggestions on how to keep APK size small:
- Use the new Android App Bundle to immediately find size savings. At Google I/O this year, we announced the Android App Bundle, which is a new publishing format from Google Play. With the Android App Bundle, you build one artifact that includes all of your app’s compiled code, resources, and native libraries for your app. You no longer need to build, sign, upload, and manage version codes for multiple APKs. This has saved developers up to 65% in app size for their users, with relatively little work upfront. To learn more, check out Android App Bundle.
- Replace PNG/JPG files (if any) with WebP assets. With lossy WebP compression, nearly identical images can be produced with significantly smaller file sizes. For vector graphics, use SVGs. For more details, check out Connectivity for billions: Optimize images and this overview of WebP.
- Replace raw audio formats (e.g. WAV) with MP3 or AAC for all audio resources. The loss in any sound quality should be imperceptible to most users, and will still deliver a quality playback/audio listening experience with less resources.
- Ensure the libraries used are up-to-date and are necessary. Consider removing duplicated libraries and update deprecated libraries. Also, when available, please use mobile optimized libraries instead of server optimized libraries. To learn more, check out ClassyShark.
- Keep DEX within reason. The dex code can take up significant space in the APK. Consider further optimizing the code to reduce the APK size. Learn more about minifying code and check out relevant details in our Building for Billions guidelines.
AliExpress knew that keeping their APK means good business sense: remember, the smaller the APK, the more installs you get. “To keep our Android Go APK size small, we first split our code into multiple modules, then used product flavors to define the specific Go and regular builds,” says Donghua Xun, Senior Android Engineer at AliExpress. “This allowed us to pick and choose feature-specific modules (e.g. live video) to exclude from our Go version. We then used a Gradle script to package this Go-edition APK, along with our regular APK, all from the same code base. We also overwrote images in third-party libraries with dummy images of a much smaller size. All this work resulted in a reduction of an Android Go APK size of 8.8MB, v.s. a regular APK size of 43MB.”
If you are interested in learning more about how you can deliver on-demand features to your users (thereby keeping initial download size light), please fill out our interest form.
Keep your memory footprint light
Android (Go edition) phones are devices that have <1GB of RAM on device. The OS is optimized to run well and efficiently in low memory environments, and a key focus for developers is to ensure that their app or game is optimized to utilize memory efficiently. When testing your APK, we look at PSS(Proportional Set Size) to see how much memory an app or game takes on cold start on a device. PSS is measured as the sum of the private memory of your app plus the proportion of shared memory that your app uses on the device.
Follow the instructions below to test memory allocations:
- With the app installed and the device connected to a workstation/laptop, launch the app and wait to arrive at the welcome screen (we recommend waiting 5 seconds to ensure that everything is loaded in)
- In terminal, run the command adb shell dumpsys meminfo<com.test.app> -d (Where <com.test.app> is the pkg_id of the app being tested e.g. com.tinder)
- Record the value in the row Total, for the column PssTotal (this value is reported in KB -> convert to MB by dividing by 1000)
- Repeat steps 2 & 3 multiple (at least 5) times and average the PssTotal(KB) value
Mercado Libre, LATAM’s largest shopping app, was able to address both memory allocations and APK size requirements by focusing their efforts on their app’s architecture. “In order to reduce the size of our APK, we first implemented multi-APK by architecture and density and then striped out any extra class or resources in external libraries through ProGuard,” says Nicolas Palermo, Engineer at Mercado Libre. “From there, we focused on our code and our resources, by analyzing whether or not we needed certain libraries, and removing the ones we didn’t. All of our images were changed to WebP where possible, and any images not converted to WebP were compressed strictly to the quality that we needed. Last, we used APK Analyzer to learn more about our memory usage to ensure our PSS was within the acceptable range.”
“I started off by targeting SDK 26 to ensure users were getting the latest Android experience. From there, I located all static functions and static variables to see if they were really necessary, and removed ones that were not. To transfer values between Activities and Fragments replace public static functions by public interfaces,” says Michel Carvajal, creator of the budgeting app Gastos Diarios 3. He adds, “I also located cycles such as While and For that executed actions for reading a database and tried to place the majority of these processes within asynchronous classes with AsyncTask. And last, I searched for ambiguous SQL statements to replace for more efficient SQL statements. All of these items together, along with a few others, collectively helped me reduce my PSS by almost 60%.”
Keep your cold startup time under 5 seconds
Perception is key here. In user testing and studies, people become frustrated after 5 seconds of waiting for an app or game to load, which leads to abandonment and uninstall. You should treat this as your window to make sure you capture a user and don’t give them an opportunity to abandon your app after they have installed your app on their phone. We always measure cold startup time as the time it takes for your app to be fully interactive to the user. It’s best to run tests for cold startup time after doing a full reboot of your test device.
“When looking at the size requirement, we focused our efforts on compression format of images, length of sound clips and resolution of images,” says Amitabh Lakhera, Vice President of Production of JetSynthesys, makers of Sachin Saga Cricket Champions. “For Startup time optimisation, reducing data load, setup and background utilities, helped achieve large time savings. In addition optimising game shaders, and avoiding checks like player profile, game balancing files and force updates significantly sped up game start. Removing internet connectivity at startup and using anti cheat tools prevented any potential misbehaviour in game by players and reduced memory usage as well.”
Overall, as you think about how to get your app ready for Android (Go edition), keep in mind the various optimizations and adjustments as outlined above. With all the work developers have done to optimize their apps and games using the guidance above, I’m confident you will be able to achieve similar results! If you would like to learn more about building for Android Go and how to optimize for global markets, check out the session from Google I/O this year.