I've implemented an service which cyclically updates the UI at a custom interval. When changing the update interval, I want to stop the current handler and start over with the new interval. As i read in other Threads before, it is not possible to interrupt a handler, after it has been fired. However the solutions mentioned, like removing callbacks and messages
handler.removeCallbacksAndMessages(null);
handler.removeCallbacks(runnable);
such as implementing a kill switch
started = false;
if(started) {
//do work..
}
did not help at all. When I restart my service with an updated interval, the handlers do not stop, causing multiple handlers running at the same time.
Does somebody know what I'm doing wrong or how to to better? Appreciate any help! Thanks!
//Mainactivity
startService(new Intent(this, updateService.class));
public class updateService extends IntentService {
private boolean started = false;
private Handler handler = new Handler();
public updateService() {
super("updateService");
}
@Override
public int onStartCommand(@Nullable Intent intent, int flags, int startId) {
// Try to stop handler when startservice is called and start new one afterwards
stop();
start();
return super.onStartCommand(intent, flags, startId);
}
public void start() {
started = true; // Didn't help
int timer = config_store.getPreference("refresh_interval"));
if (timer !=0){
handler.postDelayed(runnable, timer);
}
else {
stop();
}
}
public void stop() {
started = false;
handler.removeCallbacksAndMessages(null); // Didn't help
handler.removeCallbacks(runnable); // Didn't help
}
private Runnable runnable = new Runnable() {
@Override
public void run() {
if(started) { // Didn't help.
// Update job
doJob();
// Start over again
start();
}
}
};
}
Ok, fixed it myself: delayed handler was not the best solution for cyclically calling methos. Now using TimerTask:
public int onStartCommand(@Nullable Intent intent, int flags, int startId) {
if(mTimer != null) {
mTimer.cancel();
}
mTimer = new Timer();
int timer = Integer.parseInt(getPreference("refresh_interval")) * 1000;
mTimer.scheduleAtFixedRate(new TimeDisplayTimerTask(), timer, timer);
return super.onStartCommand(intent, flags, startId);
}
class TimeDisplayTimerTask extends TimerTask {
@Override
public void run() {
// run on another thread
mHandler.post(new Runnable() {
@Override
public void run() {
// Do job
}
});
}
}