Developing your Android app to handle slow network speed is an important task to consider.
Why it might be important to you
There are many reasons why an Android developer should care about this
- The reality is that most developers only test their app on fast WiFi connections within their location or development area.
- Different networks around the world have different properties, we often forget that our devices are not connected to high speed internet 24/7, most especially if you are building an app that cuts across several countries and regions.
- App crashing when network drops in the middle of a remote call or perhaps if network changes while user is downloading something within the app.
It is always good to handle slow connection to give users a great experience while using your app regardless of the locale or network.
Sometimes, your app might be responding slowly because your users are only paying for slow internet, users don’t usually care if network is bad, they end up cursing the app and uninstalling it, then leave a bad rating on the Play store even for their own poor internet connection.
Its best to design your app to handle the lack of network connection, provide a friendly feedback to the user and never show user a raw error message. Feedbacks can be attention grabbing alert dialogs, toast message or a simple friendly snack bar message.
A good popular practice is to Structure or Design your app to use a cache mechanism. Determine network speed when the app starts, based on that, you can display images with lower quality and others. Avoid multiple calls to the server, get all the data in one go and then use the cache, moving forward request your data from the cache.
In Android, there are ways to determine your connection speed
- Using NetworkInfo class, ConnectivityManager and TelephonyManager to determine your network type.
- Another test is to download some file from the internet & calculate how long it took vs number of bytes in the file.
- Use Facebook’s Network Connection Class library to figure out the quality of the current user’s internet connection on the fly.
Using an external library which does the job well is not a bad approach but it is essential to always know how to write your own solution as oppose to using a library.
Using NetworkInfo class, ConnectivityManager and TelephonyManager to determine your network type
Connection speed is usually slower on mobile data than on WiFi, but then that depends on your mobile data provider. Here, we check if connected to a WiFi network or mobile data, then further perform a check for which exact type of mobile data we are connected to.
Here we are checking for network info type and subtypes.
Below you can see a list of various subtypes. It shows the kbps for each subtype and then you can prioritize your task depending on where your subtype falls under mobile data.
Download some file from the internet & calculate how long it took vs number of bytes in the file
If you are connected on WiFi, you can assume that your connection would probably be fast, but this is not true in all cases, your WiFi network connection might go down temporarily or just reduce in speed. Network API will not indicate if your internet connection has dropped in the middle of your remote call.
To measure the quality of your network speed for proper handling, you need to download some file from the internet and calculate how long it took vs number of bytes.
Here we’ll be using using OkHttp library to fetch the required image file. OkHttp is an easy to use third-party library developed by Square for sending and receive HTTP-based network requests. If you haven’t used OkHttp, please do check it out.
So lets get started…
compile the OkHttp in build.grade
So we fetch the required image file and calculate how long it took to download the image by subtracting the end time from start time. The duration of the download definitely depends on the size of the file you are downloading, a file of 100kb should not take more than 6 secs to download under a fast internet connection.
Steps to be taken:
- We get the start time before the request is made and end time after request is completed.
- We subtract the end time from start time to get the actual download time in milliseconds, then divide by 1000 to get the seconds.
- We divide 1024 by time in seconds, to get the kilobyte per each sec download.
- You can determine if connection is poor, good or average by checking it against set of bandwidth range in KB per sec you have specified in the code.
- Also to get the download speed, we divide the file size by time taken to download.
A sample code below which shows each of those steps
Use Facebook’s Network Connection Class library
Facebook developed an open-sourced Network Connection Class library that lets apps figure quality of user’s connection on the fly.
Facebook also uses the technique of downloading a file from a URL to measure the user’s downstream bandwidth. It listens to existing internet traffic done by your app and notifies you when the user’s connection quality changes.
Steps to use the library:
compile the Facebook connection class
In your onCreate, get the instance of the connection class manager and device bandwidth sampler.
Here, we use OkHttp to make request for the image, start sampling before the request is made and stop sampling after request is completed and get the quality of the connection. If request fails, we stop sampling and retry 10x times until we get the quality.
Here we implement a listener and subscribe to it, so when the network’s connection quality changes.
This Connection library provides different connection qualities, If the quality of your connection cannot be accurately found, it returns Unknown.
Below are the list of the connection qualities:
POOR // Bandwidth under 150 kbps.
MODERATE // Bandwidth between 150 and 550 kbps.
GOOD // Bandwidth over 2000 kbps.
EXCELLENT // Bandwidth over 2000 kbps.
UNKNOWN // connection quality cannot be found.
Handling edge cases
Following the best practice can reduce issues you may face but there might still be problems relating to user going-in-and-out of networks. You should display a nice friendly message according to the current state of the network and turn off some features if possible.
Lastly, don’t be trapped in the assumption that your app is either always online or offline, it is usually in a gray area in between with consistent levels of connectivity. Apps which are built with this in mind provide responsive user experience under any network scenario.
Here is the Github repo for this post which shows those full examples above
detectSlowConnection - A sample app that shows different ways of detecting slow connections