How do I change the rate or period of a repeating task using ScheduledExecutorService?

11,222

I improved the answer a bit (mainly because I too had to use ScheduledExecutorService). Please use this code instead of the previous one I posted, because the previous one was really on performance, for no good reason.

private ScheduledExecutorService scheduledExecutorService;
private ScheduledFuture<?> futureTask;
private Runnable myTask;

@Override
public void onCreate(Bundle savedInstanceState) 
{
    super.onCreate(savedInstanceState);

    // Your executor, you should instanciate it once for all
    scheduledExecutorService = Executors.newScheduledThreadPool(5);

    // Since your task won't change during runtime, you can instanciate it too once for all
    myTask = new Runnable()
    {
        @Override
        public void run()
        {
            // Your code to run periodically
        }
    };
}

/**
 * This method will reschedule "myTask" with the new param time
 */
public void changeReadInterval(long time)
{
    if(time > 0)
    {       
        if (futureTask != null)
        {
            futureTask.cancel(true);
        }

        futureTask = scheduledExecutorService.scheduleAtFixedRate(myTask, 0, time, TimeUnit.SECONDS);
    }
}

Now, to reschedule your task during runtime, use the method changeReadInterval(time);

It will cancel the previous "timer" if it has been set and will reschedule a new one.

Share:
11,222

Related videos on Youtube

greencardigan
Author by

greencardigan

Spare time app developer.

Updated on November 27, 2020

Comments

  • greencardigan
    greencardigan over 3 years

    I have a modified version of the bluetooth chat sample app. I have set up a ScheduledExecutorService which sends a command over bluetooth at a predefined rate using scheduleAtFixedRate.

    I have set up a PreferenceActivity to allow the period to be modified by the user. But I'm unsure how to get the actual recurring tasks to happen with the updated period. Do I need to cancel and restart the ScheduledExecutorService somehow?

    Here's the relevant parts of my code.

    private ScheduledExecutorService scheduleTaskExecutor;
    
    public long ReadInterval = 1;
    
    ...    
    
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
            scheduleTaskExecutor = Executors.newScheduledThreadPool(5);
    ...
        // This schedule a task to run every 1 second:
        scheduleTaskExecutor.scheduleAtFixedRate(new Runnable() {
          public void run() {
    
    
            // If you need update UI, simply do this:
             runOnUiThread(new Runnable() {
                public void run() {
                // update your UI component here.
                  if (connected == true) {
                      sendMessage("READ");                
                      if (D) Log.i(TAG, "In Run!");                   
                  }
                }
            });
          }
        }, 0, ReadInterval, TimeUnit.SECONDS);      
        }
    

    And I was trying to update ReadInterval here. The ReadInterval is getting updated but the recurring command period does not get updated.

        @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        if (D)
            Log.d(TAG, "onActivityResult " + resultCode);
        switch (requestCode) {
        case REQUEST_CONNECT_DEVICE:
    ...
        case REQUEST_ENABLE_BT:
    ...
        case REQUEST_SETTINGS:
            // When returning from settings activity
            SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(this);
            String Pref = sharedPref.getString(SettingsActivity.KEY_PREF_READINTERVAL, "");
            ReadInterval = Long.valueOf(Pref);
            Toast.makeText(this, Pref,
                        Toast.LENGTH_SHORT).show();
    
            Log.d(TAG, "Settings Activity Result");
        }
    }
    
    • sasankad
      sasankad
      look at the following posthttp://stackoverflow.com/questions/1519091/scheduledexec‌​utorservice-with-var‌​iable-delay
  • greencardigan
    greencardigan about 9 years
    Thanks, this has worked.
  • Nino DELCEY
    Nino DELCEY about 9 years
    @greencardigan I updated the answer with improved code. The previous one was quite bad and not so elegant !
  • greencardigan
    greencardigan about 9 years
    This looks better. However, I had to change scheduleTaskExecutor = Executors.newScheduledThreadPool(5) to scheduledExecutorService = Executors.newScheduledThreadPool(5)to get it to work.
  • Mark Jeronimus
    Mark Jeronimus over 5 years
    Don't forget scheduledExecutorService.setRemoveOnCancelPolicy(true) to prevent a memory leak (see e.g. stackoverflow.com/a/23370049/1052284)