views:

55

answers:

1

Hey guys,

I use an AlarmManager to run a Service which tries to download a file from the web. If it fails I'd like to retry that Service in 5 minutes.

Inside the Service I run an AsyncTask to run my code. As far as I know the only way I can tell if it failed or not is from the onPostExecute().

What is the best way of implementing a retry of that Service again?

+1  A: 

Falmarri's answer is the correct one, and I do not understand your concerns.

In onPostExecute(), when you determine that things went awry:

  1. Call getSystemService(ALARM_SERVICE) to get the AlarmManager
  2. Call set() on the AlarmManager to trigger you in 5 minutes

If needed, use extras on the Intent in the PendingIntent to give you information about what to retry, or use a custom action string to distinguish retries from the scheduled alarm, or something. Note that if you use Intent extras, you will need to choose an appropriate flag with PendingIntent (e.g., FLAG_UPDATE_CURRENT).

The problem is the AlarmManager is started from one class but the AsyncTask is in another class, therefore the class that starts the AlarmManager doesn't know whether it has failed or not.

So? Multiple classes can talk to the AlarmManager. Also, feel free to pass data to your AsyncTask subclass via its constructor.

Also, you might want to consider using an IntentService rather than a Service and AsyncTask. IntentService gives you a background thread automatically. Plus, it shuts down when there is no more work to be done, which is also important, so you don't get a bunch of one-star ratings on the Market complaining about the service you keep running all of the time.

I don't want to start an AlarmManager from the onPostExecute() of my Service class.

Why not?

If I start an AlarmManager from within the Service then I'm sort of creating a recurring function where I'm calling the Service from itself.

Of course. That's what you want. It matters not a whit whether the Service or the AsyncTask or the MyOtherReallyCoolClass is the one actually talking to AlarmManager -- the component that is rescheduling the Service is the Service itself.

CommonsWare