50

how to run the async task at specific time? (I want to run it every 2 mins)

I tried using post delayed but it's not working?

    tvData.postDelayed(new Runnable(){

    @Override
    public void run() {
        readWebpage();

    }}, 100);

In the above code readwebpage is function which calls the async task for me..

Right now below is the method which I am using

   public void onCreate(Bundle savedInstanceState) {

         readwebapage();

   }

   public void readWebpage() {
    DownloadWebPageTask task = new DownloadWebPageTask();
    task.execute("http://www.google.com");

   }

   private class DownloadWebPageTask extends AsyncTask<String, Void, String> {
    @Override
    protected String doInBackground(String... urls) {
        String response1 = "";
        response1=read(); 
                   //read is my another function which does the real work    
        response1=read(); 
        super.onPostExecute(response1);
        return response1;
    }


      protected void onPostExecute(String result) {


         try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }

            TextView tvData = (TextView) findViewById(R.id.TextView01);
            tvData.setText(result);

        DownloadWebPageTask task = new DownloadWebPageTask();
        task.execute(new String[] { "http://www.google.com" });

    }

    }

This is what I my code is and it works perfectly fine but the big problem I drains my battery?

Ron
  • 22,128
  • 31
  • 108
  • 206
Shan
  • 2,822
  • 9
  • 40
  • 61
  • 1
    "I tried using post delayed but it's not working?" - this doesn't explain anything. Without more code and logcat output to show exceptions it's not easy to answer your question. – Squonk Jun 01 '11 at 20:52
  • @MisterSquonk Posted my entire code .. – Shan Jun 01 '11 at 21:11
  • 3
    Of course it drains your battery. You are fetching Web content, sleeping for 100 milliseconds, and fetching it again. That is bad for your battery and may be very expensive when your mobile phone bill comes in. – CommonsWare Jun 01 '11 at 21:21
  • None of the below methods are working what should I do??I want to fetch the webcontent every 2 mins or 5 mins.. – Shan Jun 01 '11 at 21:25

9 Answers9

79

You can use handler if you want to initiate something every X seconds. Handler is good because you don't need extra thread to keep tracking when firing the event. Here is a short snippet:

private final static int INTERVAL = 1000 * 60 * 2; //2 minutes
Handler mHandler = new Handler();

Runnable mHandlerTask = new Runnable()
{
     @Override 
     public void run() {
          doSomething();
          mHandler.postDelayed(mHandlerTask, INTERVAL);
     }
};

void startRepeatingTask()
{
    mHandlerTask.run(); 
}

void stopRepeatingTask()
{
    mHandler.removeCallbacks(mHandlerTask);
}

Note that doSomething should not take long (something like update position of audio playback in UI). If it can potentially take some time (like downloading or uploading to the web), then you should use ScheduledExecutorService's scheduleWithFixedDelay function instead.

deimian86
  • 1,127
  • 1
  • 11
  • 26
inazaruk
  • 74,247
  • 24
  • 188
  • 156
  • i have edited your code remember 2000ms = 2 seconds; 120000ms = 2 minutes. – Jorgesys Jun 01 '11 at 21:29
  • I actually fixed that before you submitted the change :) – inazaruk Jun 01 '11 at 21:38
  • Whether it is m_handlerTask.run()? – Shan Jun 01 '11 at 21:50
  • I didn't understand your question. Could you elaborate? – inazaruk Jun 01 '11 at 21:55
  • void startRepeatingTask() { m_handleTask.run(); } Whether this is right?When I post the code in eclipse it's showing an error? This code should be in onCreate right? – Shan Jun 01 '11 at 22:07
  • I was able to make it work using this article http://www.vogella.de/articles/AndroidPerformance/article.html#concurrency_threads I am starting the m_handler.run() at the end of async task ? Whether that would cause any problems? – Shan Jun 02 '11 at 01:26
  • Yes, it will. First time you will run the `doSomething` task in separate `AsyncTask` thread, but next time you will `doSomething` on UI thread. – inazaruk Jun 02 '11 at 06:28
  • Where does the Handle object come from? I have `Handler` but no Handle – CQM Nov 18 '11 at 01:50
  • @CQM, I think it is supposed to be Handler. I have edited the answer. – Lazy Ninja Mar 08 '13 at 05:11
  • Minor typo: should be m_handler.removeCallbacks instead of m_handler.removeCallback. – tarkeshwar May 15 '13 at 14:11
  • in addition to @tarkeshwar's notice of type. Another type is present. there should be a --;-- added at the end of creation of runnable – tony9099 Jul 17 '13 at 19:15
  • Is this handler implemented with AsyncTask? or are you saying we should delete AsyncTask and use handlers instead? – sorry_I_wont Jan 15 '16 at 06:43
  • Where should I put the code given above? Inside `onCreate` ? – mcExchange Apr 26 '16 at 18:48
32

Use Handler and PostDelayed:

final Handler handler = new Handler();
handler.postDelayed(new Runnable() {
    public void run() {
        readWebpage();
        handler.postDelayed(this, 120000); //now is every 2 minutes
    }
 }, 120000); //Every 120000 ms (2 minutes)
Devashish Mamgain
  • 2,077
  • 1
  • 18
  • 39
Jorgesys
  • 124,308
  • 23
  • 334
  • 268
7

you can use TimerTask instead of AsyncTask.

ex:

Timer myTimer = new Timer("MyTimer", true);
myTimer.scheduleAtFixedRate(new MyTask(), ASAP, TWO_MINUTES);


private class MyTask extends TimerTask {

    public void run(){
      readWebPage();
    }

}
Berkay
  • 1,438
  • 13
  • 8
2

When phone goes to sleep mode, to save battery, and it is quite possible to happen within 2 mins interval, Handler.postDelayed() may miss scheduled time. For such activities you should use AlarmManager, get a lock with PowerManager to prevent going to sleep back while you're running the AsyncTask.

See my post with code sample here

Also you may want to read Scheduling Repeating Alarms

Community
  • 1
  • 1
Mixaz
  • 4,068
  • 1
  • 29
  • 55
2

I suggest to go with Handler#postDelayed(Runnable). Keep in mind that this method will work only when your app is running (may be in background) but if user closes it manually or simply Android runs out of memory it'll stop working and won't be restarted again later - for that you need to use services.

final Handler handler = new Handler();
handler.postDelayed(new Runnable() {
    @Override
    public void run() {
        handler.postDelayed(this, 2 * 60 * 1000); // every 2 minutes
        /* your code here */
    }
}, 2 * 60 * 1000); // first run after 2 minutes

This code will wait 2 minutes, execute your code, and then keep doing that every 2 minutes. But if you want it to run instantly for the first time - and then start the wait-do loop, instead use:

final Handler handler = new Handler();
 /* your code here */
new Runnable() {
    @Override
    public void run() {
        handler.postDelayed(this, 2 * 60 * 1000); // every 2 minutes
         /* and also here - your code */
    }
}.run(); 

or, if your code is longer than just one method (readWebsite() in this case), and you don't want that to be duplicated:

final Handler handler = new Handler();
handler.postDelayed(new Runnable() {
    @Override
    public void run() {
        handler.postDelayed(this, 2 * 60 * 1000); // every 2 minutes
         /* your longer code here */
    }
}, 0); // first run instantly

(^ this one is just like the first example but has a 0ms delay before first run instead of 2 minutes)

(This answer is based on @Devashish Mamgain's one but I added too much details for an edit so I had to add a new one)

Nicofisi
  • 1,083
  • 1
  • 15
  • 27
0

You can use Time with Handler and TimerTask

  final Handler handler = new Handler();
        Timer timer = new Timer();
        TimerTask backtask = new TimerTask() {
            @Override
            public void run() {
                handler.post(new Runnable() {
                    public void run() {
                        try {
                            //To task in this. Can do network operation Also
                            Log.d("check","Check Run" );
                        } catch (Exception e) {
                            // TODO Auto-generated catch block
                        }
                    }
                });
            }
        };
        timer.schedule(backtask , 0, 20000); //execute in every 20000 ms*/

You can check logcat to verify whether is running or not using 'check' tag name

Joshua Pinter
  • 45,245
  • 23
  • 243
  • 245
Ishan Fernando
  • 2,758
  • 1
  • 31
  • 38
0

Execute multiple messages(Runnables) then he should use the Looper class which is responsible for creating a queue in the thread. For example, while writing an application that downloads files from the internet, we can use Looper class to put files to be downloaded in the queue. This will help you to perform async task in android...

HandlerThread hThread = new HandlerThread("HandlerThread");
  hThread.start();
  Handler handler = new Handler(hThread.getLooper());
  final Handler handler1 = new Handler(hThread.getLooper());
  final long oneMinuteMs = 60 * 1000;

  Runnable eachMinute = new Runnable() { 
   @Override
   public void run() {
    Log.d(TAG, "Each minute task executing");
    handler1.postDelayed(this, oneMinuteMs);
    sendPostRequest();
   }
  };
 // sendPostRequest();
  // Schedule the first execution
  handler1.postDelayed(eachMinute, oneMinuteMs);
sumit kumar pradhan
  • 614
  • 1
  • 6
  • 12
0

Try extending the Thread class, set a sleep time of 2000 millis and place your call into the run method. That should do it.

Egor
  • 39,695
  • 10
  • 113
  • 130
-14

You could run a loop within the AsyncTask that sleeps for two seconds between doing the tasks. Something like this:

protected Result doInBackground (Params... params) {
    while (!interrupted) {
        doWork();
        Thread.sleep(2000);
    }
}
Gyan aka Gary Buyn
  • 12,242
  • 2
  • 23
  • 26
  • 5
    Running doInBackground() in an infinite loop is really a bad idea. Ideally using AsyncTask should be a one-shot operation and shouldn't run for an extended time. – Squonk Jun 01 '11 at 20:56