Android Apps Best Practices


In this blog, wanted to cover the best practices that we adhere to keep our Android app upto date. We have hundreds of apps that we support and requires us to be on-par with the ecosystem. If you are an app developer with Indian customer as primary users and need a complete guide of managing you app, read through our experience...

For starters, we would classify the ecosystem variables as below. Your app or its listings gets affected due to change in any one of the below factors. Handling these factors usually requires new app release or changes in the listing content.

1. Google
- Play Store
- Play Services
- Android OS Releases
- Android Studio

2. Other App Stores

3. OEMs

4. Customer's Phone State

5. Network Providers
- Cellular Networks
- Wifi

6. App Code, APIs, Testing

7. 3rd Party SDK Providers

1. Google
- Play Store
Google periodically keeps updating their play store policies and developer guidelines. So you need make sure you don't ignore any of the update mailers coming and be compliant. Latest is on the SMS permissions stricture. The changes are communicated well ahead and follows an orderly process.

Few months back we saw that our app download size was more than what we saw in studio. On reaching out to google support, we came to know that some security code is being added during listing that can increase the APK size.

The next big change is the move to firebase from GCM and we are well on our way to be compliant for this change.

And you need to watch out that you keep your listing content original and to purpose.

Android Vitals provide a good way of checking the health of our app and how we fare in the real world!!

- Play Services
Play Services is a proprietary background service and API package for Android devices from Google.
Google decides which OS versions get what updates and also stop updates beyond a certain OS.
We haven't seen a calendar published for the changes or end of life support.
We adapt based on compile level errors about deprecated functions.
Once we saw our crashes increase as we used a lower level of play service than what our target SDK compilation was.

OEM customizations also can impact play services APIs.

- Android Studio
Moving away from Eclipse and using Studio was a sea change. To me, it is one of the very well developed IDE.
We make sure we build our app based on the latest version of the IDE.
Newer Pro-guard & Gradle rules are also updated with each of our release
We make good use of the in-built tools like Layout Inspector, Memory Profiler, Android Lint & Performance monitor tools.

2. Other App Stores:

One of the biggest learnings that we have is about the other app stores that customers can download their apps from. We started putting our new releases to other play stores run by the likes of Redmi, Oppo, Vivo etc as some of the customers were using older versions and not updating when newer versions were available. The default store option is not Google PLay Store in those phones.
We went about creating developer account with each one of the store and/or its aggregators to keep our app version upto date.
Yes, you have to individually update your app in all the stores when a new version is launched. And in the process you may also learn Chinese!!!

3. OEMs

We encounter a wide variety of devices from a large number of OEMs, particularly those of Redmi, Oppo, Vivo, Huawei, Lenovo etc. Each of these OEMs have done a good level of customizations to their UI & phone behaviour.
The major change from stock Android is the notification handling changes done by these OEMs. With battery life being the major focus area, broadcast receivers in these phones aren't run in the background by default. This affects the notification receipt to these devices, eventhough we get a success message from Google on accepting the push notification from our server.
In-order for customers to receive notification in these devices, the app setting within the phone needs to be changed. So your app needs to have these instructions for the customer at the right moment of engagement to make them turn-on the notification receipt.
Even then in some phones, we still find that it is not working 100% of times, when the app is not running.
Whitelisting with OEMs also always doesn't work.

And the percentage contribution of traffic from these phones keeps varying based on which event/team each of them is sponsoring.

Not only phone behavior, we see that the UI elements also differ. For example, the button design is different from one phone to another. And the phone size varies from 4 to 6 inches usually. So we need to check through for any design issues in each of these form factor.

4. Customer's Phone State
Bulk of the customers may have only a reasonable RAM [1GB or lesser] and lower memory availability. This gets even more challenging as we see that apps are not closed that frequently and it remains in the background for a days together. And propensity to keep upgrading phones is lower and we support from JellyBean onwards.
Add to that, the play services in each of the phone might be different.
Some of the phone degrades in performance with extended usage or battery condition.
All these factors puts a good challenge to build app that suits this wide range of phone states.

Split Apk, instant apps, creating bundle instead of APKs, well developed app with low memory profile are some of the ways in which we can overcome the challenges and provide an engaging experience to our customers. Avoiding animations that may not be a deal breaker is another way.
During our development & testing, battery usage, network usage, memory usage are some of the essential checks and all these can be done with Studio itself. This helps enhance customer experience.

5. Network Providers

This is one of the trickiest and challenging part in the entire ecosystem. If your app relies on lots of API calls to the server for its data, this factor has to be taken into consideration in the design of your APIs and at what times the network calls need to be made.
The network quality of service varies drastically over time & place. Based on our analysis, having tower signal indicator at the top right of the device does not guarantee speed. Users having a good network strength may not be experiencing good speed as it depends on the congestion in the tower and other factors.

A 4G enabled SIM in a phone might show that network state is LTE, but the speed of access may be slow only.
Also users not updating their plans (usually on prepaid) or those with daily limits, also experience slow speeds when they are over a certain quota.

Android provides a 'network connection state' which is 'not connected', 'is connecting', 'connected'. We give a hit when the connection is in 'connected & is-available' status but this is just the last known status of the phone. The network to the tower may not be guaranteed in this case.

One of the best practices is to gauge speed by 'First Byte Receipt Time'. We hit an image URL of about 40KB and check the response time. This gives an indication of speed of the connection. Based on it, the amount of data transfer in the API can be varied. Say for a list view instead of 30 results, you can load 10 results at a time.
And if the customer is on a wifi, you can load any of the data that you think can be cached for future use.

6. App Code, APIs & Testing

In order for us to provide a good experience inspite of the variables described above, a rigorous code review, unit testing, monkey testing under various conditions become essential. A well built regression test suite goes a long way in ensuring quality.
Some of the dos are that
1. Test the code in all android versions that the code is expected to support. Check minsdk and targetSdk in the code and decide.
2. Test for layout fitment in all sizes of phones, that it is expected to run.
3. Check how the app behaves during network interruptions, other app interruptions
4. Coming from background to foreground.
5. Updating the app vs fresh install in the device
6. Crashes that are recorded in firebase pre & post release

7. 3rd party SDKs

Every app at some point of time might have 2 or 3 3rd party SDK for specific functions. These 3rd party SDKs need to be vetted for the same rigour as your own code. In one instance, one of the 3rd party SDK was doing more network calls and that kept getting flagged that our app is consuming more bandwidth. We had to discontinue that SDK later.

There are more factors at play when we deal with the mobile app ecosystem and we keep evolving constantly with time.

Hope you got some tips reading through our experience. We will share more details in the months to come on some of the topics where we have given an overview in this blog.