How do I change the rate or period of a repeating task using ScheduledExecutorService?
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.
Related videos on Youtube
Comments
-
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 usingscheduleAtFixedRate
.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 theScheduledExecutorService
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. TheReadInterval
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"); } }
-
sasankadlook at the following posthttp://stackoverflow.com/questions/1519091/scheduledexecutorservice-with-variable-delay
-
-
greencardigan about 9 yearsThanks, this has worked.
-
Nino DELCEY about 9 years@greencardigan I updated the answer with improved code. The previous one was quite bad and not so elegant !
-
greencardigan about 9 yearsThis looks better. However, I had to change scheduleTaskExecutor = Executors.newScheduledThreadPool(5) to scheduledExecutorService = Executors.newScheduledThreadPool(5)to get it to work.
-
Mark Jeronimus over 5 yearsDon't forget
scheduledExecutorService.setRemoveOnCancelPolicy(true)
to prevent a memory leak (see e.g. stackoverflow.com/a/23370049/1052284)