Battery Optimization (Part 2)
Before going through this article, it would be helpful if you go through the first part of this.
In any application, there are generally three types of regular updates:
- User-initiated. Performing an update based on some user behavior, such as a pull-to-refresh gesture.
- App-initiated. Performing an update on a recurring basis.
- Server-initiated. Performing an update in response to a notification from a server.
In this article, we will see how to optimize each type of updates.
Optimize user-initiated requests
User-initiated requests typically occur in response to some user behavior. For example, user clicking a button to get more data or trying to perform a pull-to-refresh gesture. There are a few ways to optimize these kind of requests namely:
Throttle user requests
It means not making a request if there is no need for it. For example, if you know the two requests are going to result in the same output, we can avoid doing one of them, reducing how often the radio is being used.
One practical example for it will be user making multiple pull-to-refresh requests in a small time frame.
Use a cache
Cache data whenever possible. By caching your app’s data, you can access the local copy of the information multiple times without having to open a network connection to make new requests.
On Android 11 and higher, your app can use the same large datasets that other apps use for use cases such as machine learning and media playback. When your app needs to access a shared dataset, it can first check for a cached version before attempting to download a new copy.
Use greater bandwidth to download more data less often
When connected over a wireless radio, higher bandwidth generally comes at the price of higher battery cost, meaning that 5G typically consumes more energy than LTE, which is in turn more expensive than 3G.
But, however better bandwidth means more data can be downloaded in a small time frame. So you can check the network connection and depending on the bandwidth you can decide how much data to download and how often.
Optimize app-initiated requests
App-initiated requests typically occur on a schedule, such as an app that sends logs or analytics to a backend service. When dealing with app-initiated requests, consider the priority of those requests, whether they can be batched together, and whether they can be deferred until the device is charging or connected to an unmetered network. These requests can be optimized with careful scheduling.
Batch network requests
As we saw in the previous article, the process of turning on the radio, making a connection, and keeping the radio awake uses a large amount of power. As a result, processing individual requests at random times can consume significant power and reduce battery life. A more efficient approach is to queue a set of network requests and process them together. This allows the system to pay the power cost of turning on the radio just once, and still get all the data requested by an app.
Use WorkManager
You can use the WorkManager
library to perform work on an efficient schedule that considers whether specific conditions are met, such as network availability and power status.
Optimize server-initiated requests
Server-initiated requests typically occur in response to a notification from a server.
Send server updates with Firebase Cloud Messaging
Firebase Cloud Messaging (FCM) is a lightweight mechanism used to transmit data from a server to a particular app instance. Using FCM, your server can notify your app running on a particular device that there is new data available for it.
Compared to polling, where your app must regularly ping the server to query for new data, this event-driven model allows your app to create a new connection only when it knows there is data to download. The model minimizes unnecessary connections and reduces latency when updating information within your app.
That’s it for this article. Hope it was helpful!
Link to the other articles of this series