简体   繁体   中英

Correct way to do polling in Android app

I have to develop a simple application that every 5 seconds fetch a json from a server. I know that this will drain the battery but since I don't have control on the server, this is the only solution I have at the moment, so stay with me. (It's a demo app, the final release will be totally different)

What I did:

I created an IntentService and in his onHandleIntent I do the http request and manage the response asynchronously. Reading the docs, the IntentService is preferred to the Service. At the end, as seen in other topics, I use the AlarmManager class to recreate the intentService. That's the method:

private void repeat() {
    lastTrigger = System.currentTimeMillis();
    alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);

    Intent serviceIntent = new Intent(this, StatusPollingService.class);
    PendingIntent pendingIntent = PendingIntent.getService(this, 0, serviceIntent, PendingIntent.FLAG_UPDATE_CURRENT);
    alarmManager.set(AlarmManager.RTC_WAKEUP, lastTrigger + UPDATE_INTERVAL, pendingIntent);
}

In my onCreate in my first Activity, I simply start the service:

    serviceIntent = new Intent(BaseActivity.this, StatusPollingService.class);
    startService(serviceIntent);

My issues:

  1. When I close my application (using back button), the intentService continues to do the requests and recreates itself (as expected), so I have to kill it manually
  2. I'd like to stop to do polling every time my app goes in background and restart when goes in foreground, to limit the battery drain

My other issues:

I implemented a class that triggers a listener when the app goes in background/foreground. I implemented the interface in my BaseActivity and in my IntentService. When the app goes in background, a boolean became false and I don't execute the repeat() method. When I go in foreground, in my method onBecameForeground I simply create the service:

    serviceIntent = new Intent(BaseActivity.this, StatusPollingService.class);
@Override
public void onBecameForeground() {
    startService(serviceIntent);
}

Going in background there's no problem, but going in foreground multiple intentService are created, one intentService per every Activity I have in that moment (I see it in the log).

My questions:

  1. Is this the best way to do this job? How could I resolve these problems?
  2. If this is the best (or the less bad) way, how can I create a single instance of the IntentService?

Thank you so much for your help

If you only need it in the foreground, then I'd not bother with the alarms. Just post intents every 5 seconds to your intent service using Handler.

Supposedly there should be only one instance of the intent service, so if you post multiple intents for processing, they will get queued and handleIntent will be called in your intent service for each intent. Note that, however, that if your service is processing intents fast enough, then it may finish (and destroyed) before you post another intent - so you'll see multiple instances of the service being created. But there will only be one instance at a time.

Edit: to expand a bit, you will need the alarms when (and if) you'll be polling the server in background, so don't through that code away ;) Handler will keep "freezing up" in background as the OS doesn't count the time while the device was sleeping for the Handler postponed execution.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM