0

I have an asynctask named myAsync that performs some network operations (fetching data from server, and parsing the json).

I also have a handler created once the activity runs.

I also have a runnable in which i run the asynctask. The reason I am using runnable is because I will be using it inside a Handler's postdelayed method as I want this to be repeated every 1 minute.

Runnable runnable = new Runnable()
{
    public void run()
    {
        new myAsync ().execute();
    }
};

Then I am using the above runnable inside my onResume;

@Override
protected void onResume()
{
    super.onResume();
            handler.postDelayed(runnable, 60000);
    }

Whenever I leave the activity, I want the check to stop, so I am calling,

 handler.removeCallbacks(runnable);

However, the asynctask keeps on running non stop. What shall I do ?

tony9099
  • 4,567
  • 9
  • 44
  • 73

3 Answers3

5

The whole point of asynctask is to run a thread on the main thread. So it does not make sense to run it in Runnable()

meda
  • 45,103
  • 14
  • 92
  • 122
  • 2
    but I want it to be repeated every x amount of time, thats why I am using the handler's postdelayed method, which accepts runnables, so I am putting it inside a runnable. whats the alternative ? – tony9099 Sep 24 '13 at 16:11
4

What you can do is skip the Runnable and Handler...definitely not needed here. Assuming the AsyncTask is an inner class of your Activity, you can set a member boolean variable and check that in your doInBackground()

public Void doInBackground(Void...params)
{
     // this is a boolean variable, declared as an
     //Activity member variable, that you set to true when starting the task
     while (flag)  
     {
         // run your code
         Thread.sleep(60000);
     }

     return null; // here you can return control to onPostExecute()
                  // if you need to do anything there
}

This will make the AsyncTask sleep for a minute before running the code again. Then in onPause() or wherever you want you set the flag to false. If you need to update the UI then call publishProgress() inside your loop and put the UI code in onProgressUpdate()

meda
  • 45,103
  • 14
  • 92
  • 122
codeMagic
  • 44,549
  • 13
  • 77
  • 93
  • nice approach, haven't thought of it this way, however, when does the onPostExecute gets called in this case? I assume never. Btw, is this a reliable approach ? ie, do people use this workaround ? – tony9099 Sep 24 '13 at 16:18
  • I edited the code a little. You can after the `loop` finishes if you have anything you need to do in `onPostExecute()` – codeMagic Sep 24 '13 at 16:20
  • perfect. Can you think of other alternatives for the problem ? – tony9099 Sep 24 '13 at 16:22
  • I probably could if I thought really hard but I don't see what your concerns are with this...I can't think of anything more straightforward and easy to implement. – codeMagic Sep 24 '13 at 16:22
  • indeed. I'll give it a try and let you know. – tony9099 Sep 24 '13 at 16:22
  • let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/37958/discussion-between-tony9099-and-codemagic) – tony9099 Sep 24 '13 at 16:24
  • +1 nice , maybe because infinite loop? do you think that can happen – meda Sep 24 '13 at 16:24
  • 1
    @meda Thanks. No, it won't be infinite because you change the `flag` to false in `onPause()` which will break the loop any time the `Activity` is destroyed or something comes in front of it. – codeMagic Sep 24 '13 at 16:55
0

You can remove the AsyncTask and just do the proccess with Runnable in this way you can make the repetitions that you need. If this does not work you can set a flag to stop the proccess like said codeMagic.

runable = new Runnable() {  
 public void run() {
  try {
   //Proccess
   while (flag)  
   {
    //Proccess
    handler.postDelayed(this, 3000);
   }
  }catch(Exception e)
  {
   Log.i("Log","Error: "+e);                                        
  }
 };
handler.postDelayed(runable, 3000);



@Override
 public void onPause() {
    super.onPause();
   flag=false;
   handler.removeCallbacks(runnable);
 }

 @Override
 public void onResume() {
    super.onResume();
   flag=true;
   handler.postDelayed(runable, 3000);
 }

I hope this help.

Mtn
  • 1
  • 3
  • Can I do network stuff inside the public void run(), because as far as I can see, I am running this runnable on the UI and I cannot do network stuff there. – tony9099 Sep 25 '13 at 09:27
  • Check this: http://stackoverflow.com/questions/6531950/how-to-execute-async-task-repeatedly-after-fixed-time-intervals – Mtn Sep 25 '13 at 14:40