Making Android Apps Great Again

Aritra Roy
Aritra's Musings
Published in
11 min readMay 6, 2017

--

We all work hard for weeks and months in making our apps and desperately want them to be popular and successful. We all want our apps to reach a few hundred million users. But the problem is, we develop our apps focussing mainly on the users of the developed countries and completely forget about the major chunk of users rapidly coming in from the developing countries.

There is an expected growth of about 80% in the Android ecosystem from the emerging markets in the next few years.

This brings a huge opportunity for growth for developers as more and more users are getting access to smartphones and are starting to use apps for the first time.

But with great opportunity comes great challenges.

You have to make sure that the users from these emerging markets using super low-end devices and on very poor network connection get the exact same user experience that the users of developed countries using high-end devices and on super-fast internet connections always get.

So in this article, we are going to talk about some of the techniques you can use to make your Android apps ready for the future billion users. Let’s start making Android apps great again.

Put Your App On A Strict Diet

This is the first super-important thing that you need to look at if you want to tap into the massive emerging markets of Android users.

In most developing countries, users don’t have access to fast unmetered internet connections. For them every single megabyte of internet data counts and if your app is too big for them to download, they would rather go ahead and happily look for some alternatives.

You need to realize this bitter but true fact and try to make your apps smaller in size and guess what, it isn’t too difficult to do as well. You need to be a bit wiser from now on while choosing 3rd party libraries. The best idea is to always check the method count of the library you want to use before blindly adding it to your project.

If you need a small part (or feature) of the library, it is undeniably better to pull out that those particular classes instead of dumping the entire library.

You should start using Vector Drawables and spend some time optimizing the JPEG or PNG resources you are already using in your app. If you haven’t started using the new WebP feature in Android Studio 2.3, then you should start using that immediately.

You should also consider reusing your resources intelligently and programmatically creating variants of them thereby saving a lot of APK size.

Use WebP to significantly reduce image size

And one of the most important thing to reduce APK size is to use ProGuard or DexGuard in your app. This step can itself contribute to a significant reduction in your APK size and there is no way you can afford to skip it.

You can also try the less-used approach of on-demand asset loading in which you do not dump all your assets (like small video or audio files) directly into the app rather you load them “on-demand” only when they are really needed.

You should also be very careful while planning your app updates. I have seen many developers releasing very frequent app updates with minimal changes. You should think wisely and try to only push updates when you have made significant changes to the app. This way you can ensure that you are providing full value to your users who are using their precious internet data to update your app.

Recommended Reading

Make Your App Eat Less Memory And Run Smoothly

When you are making apps targeting the next billion users, you need to optimize them for memory, CPU and battery. Not everyone uses super high-end phones with 6GB RAM and an octa-core processor.

In developing countries, cheap low-end devices with 512MB RAM and 4-inch screen size is not an exception at all.

(Source: InnovationM.com)

You need to spend some time and effort in making your apps run smoothly even in the most low-end devices as well. One of the first things you need to look at while optimizing for memory is memory leaks. You can use this awesome library to quickly detect leaks in your app and fix them to prevent your app from consuming too much memory and crashing with the dreaded OutOfMemoryError.

It is time for you to pay close attention to concurrency on Android to ensure fast and smooth user experience on your apps running on all kinds of devices. Try to get along with Threads and make them your friend.

You should always make a conscious effort of keeping the main thread (or UI thread) of your app free for UI interactions only and put the background threads to handle everything else.

Quite often we use a lot of resource heavy animations in our app. These animations will run very well in newer high-end devices but those cheap low-end devices will fall into their knees running these animations smoothly.

You can use this amazing library developed by Facebook to categorize devices on the basis of their hardware specification and modify your app’s behavior on the basis of that.

For very low-end devices, you can disable all kinds of animations and make your app work well without them. For mid-end devices, you can disable the heavy animations and keep the light-weight ones turned on. And for high-end devices, you are free to do anything.

Recommended Reading

Start Implementing Adaptive Content Loading

This technique, if implemented properly can prove to massively improve the experience of your emerging market users. This would make your app so much more loveable and your users will love you for doing this.

The 500px app showing a list of high-quality images

Suppose you have an app that shows a list of images fetched from the internet to your users, where the user can scroll to view more images. Now if the user is on a flaky or slow network connection (like 2G or EDGE or is traveling in a vehicle), then most of those large high-quality images will not load and the user will either see a few images loaded here and there or a completely blank screen.

This is a very common problem in many apps and it needs to be solved. You can make use of the Adaptive Content Loading technique to dynamically change the quality of the images you load depending on the quality of the network the user is currently on.

You can serve lower quality images to your user if they are on a slow or poor network connection. You can use this amazing utility library, Network Connection Class to get an idea of the current network quality and fetch images based on the quality of the network.

There is a big difference between showing a lower quality image to an user and showing nothing at all.

Comparison of several variants of the same image

Most importantly, your server needs to support this kind of mechanism. You need to keep several quality variants of a particular image (very low, low, medium, high, ultra-high, etc.) on your server and provide the one that will be best suited for a particular network connection.

But the bonus point here is that if the network connection improves after some time then you can re-fetch higher quality images and replace the lower-quality ones with them. This way you can ensure that your user always gets the best possible experience even if the network connection quality changes frequently.

Recommended Reading

It’s Time To Make Your App Offline-First

I know you might be thinking, “How can I make my app 100% offline?”

You can’t. Like you can’t make the login or purchase flow in your app completely offline. At some point down the flow, you need the user to connect to the network to complete the flow. That’s absolutely necessary.

But you can always make your app offline-first.

Don’t get confused between making 100% offline apps and making offline-first apps.

It is quite sad that people tend to confuse these two and end up completely neglecting this super-important technique that has the potential to significantly improve the quality of your app.

Your primary focus should be to make your app work offline as much as possible. It is not difficult, but you may need to completely change the approach you are currently using in your app to communicate with the network.

Suppose you have a photo sharing app (like Instagram) where people can like each other’s photos. In the traditional way, when a user clicks on the “like” button, you make a network call and wait for the response. If the call succeeds, you update the view to let the user know that their “like” actually went through. Pretty simple, right?

Yes, it is simple but not a good approach for many reasons. Like , you should not block the user while you are making a network call from your app. Ideally, the user should not even know (in most situations) that your app is trying to talk to the internet. It should be done seamlessly.

Liking a photo in the Instagram app

What if while browsing the app, the internet connection drops for a few minutes and in those few minutes the user taps the “like” button on a few photos? All those operations will fail flat. Now ask yourself, is it a desirable user experience that you want your users to have?

No, certainly not. You can completely change this scenario and make the UX so much better by introducing a persistent data storage (SQLite or Realm, or whatever you want) in your app to make your app work seamlessly even when it is offline.

So from now on, whenever the user likes a photo, you update your model in the local storage and instantly reflect the change in the UI. You may or may not decide to make the network call right away. Even if you do so, you need to make sure it’s done silently and the user doesn’t get blocked in the flow.

If the network connection is poor at that time, you can try to make the request sometime in the future or batch several “like” requests together (saving battery life and bandwidth) in a single call later when your application logic deems fit.

It can eventually bring quite a lot of change in the architecture of your app, but it will be completely worth it. This will create a really amazing experience for your users, especially those on slow and intermittent network connections and help your app grow strong in emerging markets.

Recommended Reading

Improve Your App Experience Using Intelligent Content Prefetching

I will give you a typical scenario and how this amazing technique can massively improve the experience of your app in scenarios like this.

Suppose you have developed a news reader app. Now you have a user who wakes up at 6 am in the morning and takes the bus to go to the office at 8 am. It takes around an hour for the user to reach his office and he loves your app and wants to read all the latest and popular news using it while travelling.

Your app can do that right? Yes, it absolutely can, but the question is how well it can do that. In most developing countries, it is quite common for the data connection to fluctuate a lot while traveling. Most places don’t even have proper network coverage.

This can make it really difficult for your user to browse various news articles and enjoy the true experience of the app.

So how do you solve this problem and give your user the best possible experience in critical situations like this?

The solution to this problem is not very difficult actually. You have to start making your app a bit more intelligent than it was before. From the usage patterns of the user, you can see that this user opens your app every day (weekdays to be precise) at 8 am and uses it for around an hour. So now you have the opportunity to prefetch some of the popular and recent news articles every day at around 6–7 am when the user is still at his home and is on an unmetered WiFi connection.

So, now when the user opens up your app and tries to read some articles, they are already cached locally and just waiting to be read. So even if the network connection drops or gets terribly slow, the user doesn’t need to load most of the data as they are already there in your local database.

You can do this easily by scheduling a prefetching service using an AlarmManager or JobScheduler. But I would personally recommend you to use Evernote’s Android Job which automatically switches between JobScheduler, AlarmManager and GcmNetworkManager depending on the Android version of the user and it’s super easy to use as well.

This technique can create a really smooth and amazing experience for your users no matter what kind of network connection they are on.

Recommended Reading

I hope that you will start implementing some (or maybe all) of these techniques in your app to improve the experience for your users using low-end devices and on poor quality network connections and make your app grow successfully in the emerging markets.

If you liked this article, don’t forget to share and recommend it to other fellow developers as well. Learn and let the knowledge spread.

If you have found this useful, then please consider recommending and sharing it with your friends and other developers. This article was originally published on TechBeacon.

--

--

Design-focused Engineer | Android Developer | Open-Source Enthusiast | Part-time Blogger | Catch him at https://about.me/aritra.roy