Reducing the battery impact of apps that downloads content over a smartphone radio
If I'm building a smartphone app that regularly downloads data from a server, and also intermittently uploads data (analytics, ads, etc.) what can I do to minimize the battery life impact of those transfers?
The battery impact of transfers using the wireless radio (2G, 3G, LTE, etc.) is particularly significant. Is there anything about the power-use profile of the wireless radio that should affect my choices of when, what, and how to transfer data in order to minimize its impact on battery life?
Solution 1:
This answer is summarized from The Android Training class, Transferring Data Without Draining the Battery which explains how to minimize the battery life impact of downloads and network connections, particularly in relation to the wireless radio.
In particular Optimizing Downloads for Efficient Network Access explains the wireless radio state machine in some detail and goes on to explain how your app's connectivity model should interact with it to minimize the related battery drain.
The wireless radio state machine
Reference
Every time you create a new network connection the radio will transition to the full power state. This transition typically takes around 2 seconds, so to minimize latency, the radio introduces a delay to postpone the transition to lower energy states.
A typical 3G radio will remain at full power for 5 seconds after your transfer is complete, before waiting a further 12 seconds at the low energy state before moving to standby. In total the radio will draw power for nearly 20 seconds every time you make a connection.
This approach can lead to inefficiencies for apps running on modern smartphone OSs, where apps run both in the foreground (where latency is important) and in the background (where battery life should be prioritized).
Solutions
The key to minimizing the effect of downloads on your battery is recognizing that the frequency of transfers has a more dramatic impact than the size of the downloads. In practical terms prefetching and and queuing / bundling your transfers are particularly effective.
Knowing that every time you initiate a connection you potentially cause the radio to draw power for nearly 20 seconds, it's important to bundle your data transfers so that you're effectively phase-shift transfers that are due to occur within a similar time window so that you're transferring as much data as possible during each transfer session to minimize the number of sessions.
Similarly, prefetching allows you to download all the data you are likely to need for a given time period in a single burst, over a single connection, at full capacity. By front loading your transfers, you reduce the number of radio activations required to download the data, conserving battery life, improving latency, lowering bandwidth, and reducing download times.
However, prefetching also introduces the risk of increasing battery drain and bandwidth use by downloading data that isn't used.
How aggressively you prefetch depends on the size of the data being downloaded and the likelihood of it being used. Generally speaking, it's good practice to prefetch data such that you will only need to initiate another download every 2 to 5 minutes, and in the order of 1 to 5 megabytes.
It's also generally more efficient to reuse existing network connections rather than creating new ones. Reusing connections also allows the network to more intelligently react to congestion and related network data issues.
Solution 2:
I recommend you add a "How often to sync" preference to your app's settings -- so the user has some say in balancing data freshness vs. battery usage. Different users have different priorities.