Posted by Niharika Arora, Developer Relations Engineer
The Android operating system brings the power of computing to everyone. This vision applies to all users, including those on entry-level phones that face real constraints across data, storage, memory, and more.
This was especially important for us to get right because, when we first announced Android (Go edition) back in 2017, people using low-end phones accounted for 57% of all device shipments globally (IDC Mobile Phone Tracker).
What is Android (Go edition)?
Android (Go edition) is a mobile operating system built for entry-level smartphones with less RAM. Android (Go edition) runs lighter and saves data, enabling Original Equipment Manufacturers (OEMs) to build affordable, entry-level devices that empower people with possibility. RAM requirements are listed below, and for full Android (Go edition) device capability specifications, see this page on our site.
Year
2018
2019
2020
2021
2022
2023
Release
Android 8
Android 9
Android 10
Android 11
Android 12
Android 13
Min RAM
512MB
512MB
512MB
1GB
1GB
2GB
Android (Go edition) provides an optimized experience for low-RAM devices. By tailoring the configuration and making key trade-offs, we’re able to improve speed and performance for low-end devices and offer a quality phone experience for more than 250M people around the world.
Recent Updates
We are constantly making phones powered by Android (Go edition) more accessible with additional performance optimizations and features designed specifically for new & novice internet users, like translation, app switching, and data saving.
Below are the recent improvements we made for Android 12:
Faster App Launches
Longer Battery Life
Easier App Sharing
More Privacy Control
Why build for Android (Go edition)?
With the fast growing & easily accessible internet, and all the features available at low cost, OEMs and developers are aiming & building their apps specifically for Android (Go edition) devices.
Fast forward to today — over 250 million+ people worldwide actively use an Android (Go edition) phone. And also considering the big OEMs like Jio, Samsung, Oppo, Realme etc. building Android (Go edition) devices, there is a need for developers to build apps that perform well especially on Go devices.
But the markets with the fast growing internet and smartphone penetration can have some challenging issues, such as:
Your app is not starting within the required time limit.A lot of features/required capabilities increases your app size How to handle memory pressure while working on Go apps?
Optimize your apps for Android (Go edition)
To help your app succeed and deliver the best possible experience in developing markets, we have put together some best practices based on experience building our own Google apps Gboard & Camera from Google.
Approach
Phases
Description
DefineBefore starting any optimization effort, it’s important to define the goals. Key Performance Indicators (KPIs) have to be defined for the app.
KPIs can be common across different apps and some can be very specific. Some examples of KPIs can be
Common to all appsApp Crash Rate
Common to all appsEnd to end latency for CUJ – Camera Shot
Specific to Camera appApp Not Responding RateCommon to all apps
Once KPIs are defined the team should agree on the target thresholds. This can be derived from the minimum user experience/benchmarks in mind.KPIs should ideally be defined from the perspective of balancing User Experience and technical complexity.BreakdownOnce KPIs are defined, the next steps could be to break down a given KPI into individual signal metrics.
For example → End to end latency for CUJ (shots in Camera) can be divided into → Frame capture latency, image processing latency, time spent on saving a processed image to disk etc.Similarly, App Crash Rate can be bucketed into → Crash due to unhandled errors, Crash due to high memory usage, Crash due to ANR etc.BenchmarkBenchmark or measure the KPI values and individual metrics to identify current performance.
If KPI targets are met, things are good. If not → identify the bottlenecks by looking at the individual breakdowns.Repeat the process
After optimizing a certain bottleneck go back and benchmark the metrics again to see if the KPI targets are met. If not, repeat the process. If yes, great job!Add Regular regression testThat either runs for every change or in some frequency to identify regressions in KPIs. It is more difficult to debug and find sources of regressions or bugs than to not allow them to get into the codebase. Don’t allow the changes that fail the KPI goals unless the decision is to update the KPI targets.
Try to invest in building a regression infrastructure to deal with such issues in early stages.Decide on how often tests should run? What should be the optimal frequency for your app?
Optimize App Memory
Release cache-like memory in onTrimMemory(): onTrimMemory() has always proven useful for an app to trim unneeded memory from its process. To best know an app’s current trim level, you can use ActivityManager.getMyMemoryState(RunningAppProcessInfo) and then try to optimize/trim the resources which are not needed.
void onKeyboardViewCreated(View keyboardView) {
this.keyButtonA = keyboardView.findViewById(…);
…
}
The |keyboardView| might be released at some time, and the |keyButtonA| should be assigned as null appropriately at some time to avoid the view leak.
ClassA obj = new ClassA(“x”);
// … something
obj = new ClassB(“y”);
GC should clean this up eventually.
if ClassA allocates native resources underneath and doesn’t cleanup automatically on finalize(..) and requires caller to call some release(..) method, it needs to be like this
ClassA obj = new ClassA(“x”);
// … something
// Explicit cleanup.
obj.release();
obj = new ClassB(“y”);
else it will leak native heap memory. Optimize your bitmaps: Large images/drawables usually consume more memory in the app. Google apps identified and optimized large bitmaps that are used in their apps.
For example: Gboard’s glide typing feature needs to show an overlay view with a bitmap of trails, which can only has the alpha channel and apply a color filter for rendering.
// Creating the bitmap for trails.
trailBitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ALPHA_8);
…
// Setup paint for trails.
trailPaint.setColorFilter(new ColorMatrixColorFilter(new ColorMatrix(new float[] {
0, 0, 0, 0, (color >> 16) & 0xFF,
0, 0, 0, 0, (color >> 8) & 0xFF,
0, 0, 0, 0, color & 0xFF,
0, 0, 0, 1, 0
})));
…
// onDraw
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
if (trailBitmap != null) {
canvas.drawBitmap(trailBitmap, 0, 0, trailPaint);
}
}
A screenshot of glide typing on GboardCheck and only set the alpha channel for the bitmap for complex custom views used in the app. This saved them a couple of MBs (per screen size/density).While using Glide, The ARGB_8888 format has 4 bytes/pixel consumption while RGB_565 has 2 bytes/pixel. Memory footprint gets reduced to half when RGB_565 format is used but using lower bitmap quality comes with a price too. Whether you need alpha values or not, try to fit your case accordingly.Configure and use cache wisely when using a 3P lib like Glide for image rendering.Try to choose other options for GIFs in your app when building for Android (Go edition) as GIFs take a lot of memory.The aapt tool can optimize the image resources placed in res/drawable/ with lossless compression during the build process. For example, the aapt tool can convert a true-color PNG that does not require more than 256 colors to an 8-bit PNG with a color palette. Doing so results in an image of equal quality but a smaller memory footprint. Read more here.You can reduce PNG file sizes without losing image quality using tools like pngcrush, pngquant, or zopflipng. All of these tools can reduce PNG file size while preserving the perceptive image quality.You could use resizable bitmaps. The Draw 9-patch tool is a WYSIWYG editor included in Android Studio that allows you to create bitmap images that automatically resize to accommodate the contents of the view and the size of the screen. Learn more about the tool here.
Recap
This part of the blog outlines why developers should consider building for Android (Go edition), a standard approach to follow while optimizing their apps and some recommendations & learnings from Google apps to improve their app memory and appropriately allocate resources.
In the next part of this blog, we will talk about the best practices on Startup latency, app size and the tools used by Google apps to identify and fix performance issues.