In this post I will cover a few important guidelines on how reduce power consumption of polling Android applications, i.e. applications that regularly connect to the internet, and get more out of the phone battery. I have crated a small sample app that puts all of the tricks into practice by setting up a background service that polls Twitter trends regularly and logs them to a file. By downloading the sample app and applying these guidelines, you will reduce the power consumption of your app by magnitudes, if you haven’t before. Click here to download the sample app. 

 

 

 

We will cover four guidelines: 

1. Synchronize you polls with other apps 

2. Make polls short 

3. Manage your connections 

4. Stop your services 

 

Synchronizing polls 

Synchronizing you polls with other polling apps will reduce how often the radio is activated. It is achieved by using  AlarmManager with setInexactRepeat and a interval constant provided in AlarmManager, e.g. INTERVAL_HALF_HOUR.  These constants are special in that AlarmManager.setInexactRepeat will fire the intents at a regular intervals simultaneously, but not at exactly specified times. In the sample apps we have a BroadcastReceiver (Booter)  which wakes up at boot which in turn kick off a Service (Poller) at regular synched intervals: 

[java]
public void onReceive(Context context, Intent rIntent) {
if (rIntent.getAction().equals(Intent.ACTION_BOOT_COMPLETED)) {
AlarmManager am = (AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
Intent intent = new Intent(context, Poller.class);
PendingIntent pIntent = PendingIntent.getService(context,0,intent, 0);
long interval = AlarmManager.INTERVAL_FIFTEEN_MINUTES;
long firstPoll = System.currentTimeMillis();
am.setInexactRepeating(AlarmManager.RTC, firstPoll, interval, pIntent);
}
}
[/java] 

If apps don’t use this, this is what will happen when three different apps poll at random times within an interval: 

 

 

As you can see, the radio has to stay in DCH and FACH state for a long time after each request and response transaction (user data) has been completed.  If they sync the polls (HTTP requests) it looks like this: 

 

As you can tell, this will save lots of power for each poll cycle. 

Make sure to use AlarmManager.RTC, not AlarmManager.RTC_WAKEUP, i.e. don’t wake up the application unless some other app is also being woken up. Google services run regularly and will make sure your app wakes up now and then. 

Execute polls in as short time as possible 

A poll with several requests and responses spread out over time will force the radio to stay in a high power state for long time. If a poll consists of multiple requests, fire them all before waiting for responses if they are independent. If not, then try to reduce the poll to as few requests as possible, e.g. by changing the server interface. If you don’t have control over the server, then use features like multiquery or batched queries, if supported (e.g. Facebook). If you control the server, make sure it’s response times are short (within a couple of seconds). The sample project only has a single request, so this tip is not illustrated, but is straightforward to implement. 

Minimizing the amount of data sent and received saves battery. Thus, also make sure to set the Accept-Encoding HTTP header to “gzip”. Twitter and Facebook APIs both support gzip. The sample project defines two Interceptors and an Entity to add support for compression, which makes it transparent when using the client. 

[java]
httpclient.addRequestInterceptor(new GzipHttpRequestInterceptor());
httpclient.addResponseInterceptor(new GzipHttpResponseInterceptor());
HttpGet httpget = new HttpGet(“http://api.twitter.com/1/trends/current.jons”);
HttpResponse response = httpclient.execute(httpget);
[/java]

Manage HTTP connections 

HttpURLConnection has a well known bug that leave connections hanging by not closing them as they should, when using HTTP GET. Specifically, it leaves connections hanging when using the Twitter API. After a minute or two after your requests is sent, the server forcibly closes the connection, causing a big power surge due to the radio link becoming active, even though your application is not sending or receiving any data. In the sample project I use the Apache client instead and make sure to close the connection forcibly using 

[java]
httpclient.getConnectionManager().shutdown();
[/java]
Stop services 

Services should be short lived and stopped as soon as they have finished their task, using stopSelf(). Have it wake up using intents when needed, e.g. using AlarmManager. 

Sample app 

In the sample app, the Poller class is only activated by the intent setup by the Booter class as you saw above. When an intent is fired, the Poller is activated by a call to onStart, which causes a poll to Twitter. After the poll, the Poller shuts down with a single line, causing it to not use any CPU until next intent fires it up.

Sort by

  • By Dia Johnigan
    29th January 2011.
    21:11

    Great job for posting such a valuable website. Your web log is not only helpful but it is additionally very artistic too. There are often hardly any those who could create not so simple articles that artistically. Keep up the nice writing

    Thumb up 0 Thumb down 0

  • By webcam jobs
    4th February 2011.
    01:58

    Highest paying webcam modeling site

    Thumb up 0 Thumb down 0

  • By tony
    29th March 2011.
    14:11

    Hi, @hajons, thanks for sharing the tips, but it seems that the download link of the sample app is broken :) , so will you please send a me a copy via email(tony_kwok[@]msn[dot]com), thanks a lot!

    Thumb up 0 Thumb down 0

  • By max hardy
    9th May 2012.
    11:37

    w8 While Compare with 2.3 Mobile Hardware’s Not possible to provide 2.3 OS to w8 But in w8 Low Internal Memory And Ram so Unable Install More app & games. Please update the OS to Install Apps to External card More Useful then no Call Recording,no task manager, no File manager,No Shortcut in Status bar(Bluetooth ,WiFi).

    Thumb up 0 Thumb down 0