1

I'd like to create an AsyncTask that sits in the background and calls a web service every X seconds.

    private class BackgroundTask extends AsyncTask<Integer, Integer, Boolean> {
    protected Boolean doInBackground(Integer... params) {
        if (params.length > 0) {
            int intUserId = params[0];

            if (intUserId != -1) {
                boolean blnRunning = true;
                while (blnRunning) {
                    // perform query

                    try {
                        this.wait(15000);
                    }
                    catch (InterruptedException e) {
                        blnRunning = false;
                    }
                }
            }
        }

        return false;
    }

    protected void onPostExecute(Boolean blnLaunchStoreFavorites) {
        // do something?
    }
}

This is what I have.

Shortly after this.wait() is called, I get an error down in the bowels of ThreadPoolExecuter.class.

Uncaught handler: thread AsyncTask #2 exiting due to uncaught exception
java.lang.RuntimeException: An error occured while executing doInBackground()
at android.os.AsyncTask$3.done(AsyncTask.java:200)
at java.util.concurrent.FutureTask$Sync.innerSetException(FutureTask.java:273)
at java.util.concurrent.FutureTask.setException(FutureTask.java:124)
at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:307)
at java.util.concurrent.FutureTask.run(FutureTask.java:137)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1068)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:561)
at java.lang.Thread.run(Thread.java:1096)

I'm not quite sure what is going on here. Any ideas?

Andrew
  • 20,756
  • 32
  • 99
  • 177
  • Try putting another catch block after the one for InterruptedException but have it catch Exception and then use printStackTrace to see what exception is being thrown. – Squonk Apr 05 '11 at 20:35
  • If this is a long running task, then maybe you should be using a Service. – Intrications Apr 05 '11 at 20:48

2 Answers2

1

What about using Thread.sleep(15000) instead? Or are you making use of the notify semantics?

Also, is there a "caused by ..." entry in logcat as well?

Matthew
  • 44,826
  • 10
  • 98
  • 87
1

Firstly, this is going to kill your battery. Secondly, if you really, really want to do this, you should use a Service rather than an AsyncTask. The latter is only supposed to be used for short lived, one-time uses, not for continuous background polling.

dave.c
  • 10,910
  • 5
  • 39
  • 62
  • How would I make the Service sleep? – Andrew Apr 05 '11 at 22:43
  • @Andrew you could use [`Handler#postdelayed()`](http://developer.android.com/reference/android/os/Handler.html#postDelayed%28java.lang.Runnable,%20long%29) on a `Runnable` – dave.c Apr 05 '11 at 23:17
  • I'm a little confused about one thing. postDelayed takes a Runnable (with my web service code) and a long (time in milliseconds) that is the time from now at which the Runnable should be executed. My issue is, I want this to happen indefinitely, X amount of times, until I stop the Service. – Andrew Apr 06 '11 at 14:38
  • @Andrew so the last thing that your runnable will do after it has finished its work is to `removeCallbacks()` then `postDelayed()` on itself. Have a look at [this example](http://stackoverflow.com/questions/4302060/self-updating-every-10-seconds-widget-handler-postdelayed-problem) – dave.c Apr 06 '11 at 14:56
  • Though I do have to ask, why is using a Runnable & Handler less strenuous on the battery when done in a Service, as opposed to a Thread or AsyncTask? – Andrew Apr 06 '11 at 22:02
  • It's the fact that you are performing a poll every 15 seconds that will kill your battery, whether it's done with an `AsyncTask` or a `Service`. However if it is functionality that you need for your app then the best way to do it is with a `Service`. – dave.c Apr 06 '11 at 23:41