How to make Async task execute repeatedly after some time interval just like Timer...Actually I am developing an application that will download automatically all the latest unread greeting from the server and for that purpose I have to check for updates from server after some fixed time intervals....I know that can be easily done through timer but I want to use async task which I think is more efficient for android applications.
5 Answers
public void callAsynchronousTask() {
final Handler handler = new Handler();
Timer timer = new Timer();
TimerTask doAsynchronousTask = new TimerTask() {
@Override
public void run() {
handler.post(new Runnable() {
public void run() {
try {
PerformBackgroundTask performBackgroundTask = new PerformBackgroundTask();
// PerformBackgroundTask this class is the class that extends AsynchTask
performBackgroundTask.execute();
} catch (Exception e) {
// TODO Auto-generated catch block
}
}
});
}
};
timer.schedule(doAsynchronousTask, 0, 50000); //execute in every 50000 ms
}

- 15,499
- 6
- 40
- 50
-
3A Async Task anyway runs in its own thread. Why run it on a handler ? – Siddharth Feb 11 '13 at 16:21
-
9Yes, the async task does run on a separate thread, but cannot be started from other threads than the UI thread. The handler, I guess, is there for allowing that. – r1k0 Jul 03 '13 at 14:28
-
A good solution would be using ScheduledThreadPoolExecutor - http://stackoverflow.com/a/14377875/1433187 – Khobaib Mar 22 '14 at 19:36
-
Should the `TimerTask` be canceled in `onPause` so the `Task` doesn't keep running after leaving the activity? – theblang Jun 18 '14 at 15:03
-
Awesome.. <3 I am using this to update the conversation view of my app.. tnx! – mboy Jul 11 '14 at 13:51
-
6This technique leaves dangling references should the Activity that starts these AsyncTasks is killed (by an orientation change or an OS interruption like a phone call). So if you're happy with your programming crashing at these times, then use this method by all means. – SMBiggs Jan 07 '15 at 22:49
-
1@ScottBiggs What technique would be better/not crash? – colti Apr 16 '15 at 20:54
-
2@colti: Haven't found a good solution. I've abandoned ASyncTasks except for very simple stuff. For more complex actions I use Services (yeah, I know, the overhead is a pain-in-the-a$$, but at least it doesn't crash as much. Just be careful to clean up and not leave dangling Services). – SMBiggs Apr 17 '15 at 04:40
-
This code freeze UI. I am using Service. There are 4 different API call. – Hardik Joshi Mar 20 '17 at 08:38
//Every 10000 ms
private void doSomethingRepeatedly() {
Timer timer = new Timer();
timer.scheduleAtFixedRate( new TimerTask() {
public void run() {
try{
new SendToServer().execute();
}
catch (Exception e) {
// TODO: handle exception
}
}
}, 0, 10000);
}

- 687
- 7
- 9
-
2It is recommend to favour ScheduledThreadPoolExecutor over Timer for all new code in the android documentation https://developer.android.com/reference/java/util/Timer.html – Martin O'Shea Jun 06 '16 at 19:34
wouldn't it be more efficient to create a service and schedule it via Alarm Manager?

- 9,006
- 5
- 25
- 38
-
1Create a service is a pain, soo many things to take care on a service. I rather just use a Timer. – Siddharth Feb 11 '13 at 16:20
-
2Services are easy to start and stop. Plus, they are not tied to the UI thread. So yes, I'd use a Service. – IgorGanapolsky Jul 27 '13 at 10:20
-
@IgorGanapolsky yes they are. But they also are a hassle, why would they create asyntask, timer, and these modules for smaller operations if they were non sense and everything would be done via a service ? – tony9099 Sep 25 '13 at 14:58
-
1@tony9099 AsyncTask is intended for updating the UI thread upon completion. Service is not. As far as Timer - it's neither here nor there - it is not relevant for comparison between AsyncTask and Service... – IgorGanapolsky Sep 25 '13 at 15:01
-
@IgorGanapolsky exactly, however, if you reread the question carefully, the user wants to check some stuff on server, fetch, and update the UI; a scenario ideal for asynctask. – tony9099 Sep 25 '13 at 15:12
-
2I agree with Igor. Because of the problem of how Activities are killed when a device is rotated (and other times), AsyncTasks are guaranteed crashes unless very very carefully treated (which they are not in these examples). The real solution is to bite the bullet (yeah I know, it IS a pain) and do Services. – SMBiggs Jan 07 '15 at 22:51
You can just a handler:
private int m_interval = 5000; // 5 seconds by default, can be changed later
private Handle m_handler;
@Override
protected void onCreate(Bundle bundle)
{
...
m_handler = new Handler();
}
Runnable m_statusChecker = new Runnable()
{
@Override
public void run() {
updateStatus(); //this function can change value of m_interval.
m_handler.postDelayed(m_statusChecker, m_interval);
}
}
void startRepeatingTask()
{
m_statusChecker.run();
}
void stopRepeatingTask()
{
m_handler.removeCallback(m_statusChecker);
}
But I would recommend you to check this framework: http://code.google.com/intl/de-DE/android/c2dm/ Is a different approach: the server will notify the phone when something is ready (thus, saving some bandwidth and performance:))

- 673
- 1
- 6
- 17
-
thanks alot.Actually I am just developing the client side of the application.Server side is already working for the same application developed for iphone and I have to use the same server for android – Waseem Jun 30 '11 at 09:12
-
1I'm new to threading in android. Where are you passing the runnable to the handler? – Dheeraj Bhaskar Jan 18 '13 at 21:37
-
2to answer @DheeB, the answerer does not mention it here, though it should be during instantiation like this m_handler = new Handler(m_statusChecker); Another reason this solution might not work, because the question is clearly indicating that there will be network operations "download automatically all the latest unread greeting from the server".. however, although you are using a handler, this handler/runnable is still running in the UI thread which is still blocking. You need to start it in a seperate thread manually. – tony9099 Sep 25 '13 at 15:10
The accepted answer is problematic. Using TimerTask() for activating async task via handler is a bad idea. on orientation change you must remember to cancel also the timer and the handler calls. if not it will call the async task again and again on each rotation. It will cause the application to blow up the server (if this is rest http get request) instead of X time - eventually the calls will be instance many calls on each second. (because there will be many timers according to the number of screen rotations). It might crush the application if the activity and the task running in background thread are heavy. if you use the timer then make it a class memebr and cancel it onStop():
TimerTask mDoAsynchronousTask;
@Override
public void onStop(){
super.onStop();
mDoAsynchronousTask.cancel();
mHandler.removeCallbacks(null);
...
}
public void callAsynchronousTask(final boolean stopTimer) {
Timer timer = new Timer();
mDoAsynchronousTask = new TimerTask() {
@Override
public void run() {
mHandler.post(new Runnable() {
...
Instead try to avoid async task, and if you must then use scheduler service to run the async task. or the application class such as in this nice idea: https://fattybeagle.com/2011/02/15/android-asynctasks-during-a-screen-rotation-part-ii/
Or use simple handler (without the timer, just use postDelayed) and also good practive is to call cancel the async task onStop(). this code works fine using postDelayed:
public class MainActivity extends AppCompatActivity {
MyAsync myAsync = new MyAsync();
private final Handler mSendSSLMessageHandler = new Handler();
private final Runnable mSendSSLRunnable = new Runnable(){
..
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ConnectivityManager connMgr = (ConnectivityManager)
getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo networkInfo = connMgr.getActiveNetworkInfo();
if (networkInfo != null && networkInfo.isConnected()) {
mSendSSLMessageHandler.post(mSendSSLRunnable);
}else
..
@Override
public void onStop(){
super.onStop();
if ( progressDialog!=null && progressDialog.isShowing() ){
progressDialog.dismiss();
}
mSendSSLMessageHandler.removeCallbacks(mSendSSLRunnable);
myAsync.cancel(false);
}
private final Runnable mSendSSLRunnable = new Runnable(){
@Override
public void run(){
try {
myAsync = new MyAsync();
myAsync.execute();
} catch (Exception e) {
// TODO Auto-generated catch block
}
mSendSSLMessageHandler.postDelayed(mSendSSLRunnable, 5000);
}
};
class MyAsync extends AsyncTask<Void, Void, String> {
boolean running = true;
@Override
protected void onPreExecute() {
super.onPreExecute();
progressDialog = ProgressDialog.show
(MainActivity.this, "downloading", "please wait");
}
@Override
protected String doInBackground(Void... voids) {
if (!running) {
return null;
}
String result = null;
try{
URL url = new URL("http://192...");
HttpURLConnection urlConnection = (HttpURLConnection)
url.openConnection();
InputStream in = new BufferedInputStream (urlConnection.getInputStream());
result = inputStreamToString(in);
}catch(Exception e){
e.printStackTrace();
}
return result;
}
@Override
protected void onCancelled() {
boolean running = false;
}
@Override
protected void onPostExecute(String s) {
super.onPostExecute(s);
progressDialog.dismiss();
try {
..
} catch (JSONException e) {
textView.append("json is invalid");
e.printStackTrace();
}
}
}

- 1,083
- 1
- 11
- 14