How to execute Async task repeatedly after fixed time intervals

AndroidAndroid AsynctaskAndroid ServiceTimertask

Android Problem Overview


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.

Android Solutions


Solution 1 - Android

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
}

Solution 2 - Android

  //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);
                     }

Solution 3 - Android

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:))

Solution 4 - Android

wouldn't it be more efficient to create a service and schedule it via Alarm Manager?

Solution 5 - Android

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();
        }

    }


}

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionWaseemView Question on Stackoverflow
Solution 1 - AndroidRaselView Answer on Stackoverflow
Solution 2 - Androidritesh4326View Answer on Stackoverflow
Solution 3 - AndroidkikosoView Answer on Stackoverflow
Solution 4 - AndroidRichieView Answer on Stackoverflow
Solution 5 - AndroidUdi ReshefView Answer on Stackoverflow