Android - Service or IntentService?

518 views Asked by At

I have an app that runs certain "long" process when it is opened or when the device is booted.

The process performs certain amount of downloads via the download manager, and when the process finishes it sends a broadcast event to the app, to capture some analytics.

As I understand, whenever the boot broadcast event is called, the Application class is intantiated (if not in memory already).

Application class is also initiated when the user opens the app.

Based on that, the code to run the proccess is placed inside onCreate method of the Application class. (the process starts a new thread from there)

However, it appears that the "long" process is taking more than the time-to-live of the boot broadcast receiver (about 10s?), so the app process is killed. Then a couple of seconds later, after the download is finished a second broadcast is sent and the app is started again calling Application.onCreate again, with some undesirable effects.

The process was expected to run in a single linear way and not calling again onCreate.

As this process happens only once, I was thinking on creating a Service to give more time to the app to stay alive. However the process depends on DownloadManager so:

1) Using IntentService won't work (as I understand) because the process is still killed after handleIntent returns. The process creates new threads so its tasks are async, and handleIntent method will return before the whole process finishes.

2) Should I create a Service which is simply 'alive' for some time and then is stopped after the process finishes?

3) As an additional question, if I have a running Service, will Application class be instantiated and kept in memory until the Service is stopped?

2

There are 2 answers

0
David Wasser On BEST ANSWER

If you do this only once, you should just create your own Service. When your app starts, call startService(). In onStartCommand() of your Service, start a background Thread that does what you want and return START_STICKY (This keeps your Service running until you stop it). When the Thread completes, call stopSelf() on the Service.

Of course, you can use IntentService, but that class is just an extension of Service that provides another layer of convenience for you. IntentService manages a pool of background threads and takes care of starting and stopping the Service when it runs out of work. This is probably overkill for what you need, but go ahead and use it if you want. The tradeoffs here are negligible.

NOTE: <opinion>For some reason, lots of developers seem to like certain "fad" solutions, like AsyncTask, IntentService, and Event Bus. There are plenty of other ways to solve problems. There is no "one size fits all" in software development.</opinion>

0
Matt Wolfe On

You could still use an Intent Service, you just need to block while the background task is running. Implementation could work like this:

Put it in a service, an IntentService could work like so:

 public class DownloadIntentService extends IntentService { 

  @Override
  protected void onHandleIntent(Intent intent) {
     //get url or whatever from intent
     //kick off async code to start the download, something like eg:
      DownloadTask downloadTask = new DownloadTask(url);
      downloadTask.setListener(new Listener() {
          public void onComplete(Download download) {
              DownloadIntentService.this.notify();
          }
       }
       downloadTask.start()
       wait();

  }