Reputation: 327
I have an Android library that has a ScheduledThreadPoolExecutor. It executes a task every two seconds to check for a condition and it is started when the application calls the enable() function of the library. When the application calls the disable() function, which then cancels the ScheduledFuture task and calls shutdownNow() on the executor. The problem is that it is not stopping. In the logs for the app, I can see disable() being called and see where Exec Shutdown is being reached, but I still see the Exec Runnable message running in the background. In fact, it keeps running until I kill the app. Any ideas why the task is not stopping? Relevant code below:
private ScheduledThreadPoolExecutor exec;
private ScheduledFuture<?> sf;
private void enable(){
exec = new ScheduledThreadPoolExecutor(1);
long period = 2000;
exec.setExecuteExistingDelayedTasksAfterShutdownPolicy(false);
exec.setContinueExistingPeriodicTasksAfterShutdownPolicy(false);
sf = exec.scheduleAtFixedRate(new SwitchCheck(), 0, period, TimeUnit.MILLISECONDS);
}
private void disable(){
if(exec != null) {
try {
Log.d(LOG_TAG,"Exec Shutdown");
sf.cancel(true);
exec.shutdownNow();
exec = null;
} catch (Exception e){
e.printStackTrace();
}
}
}
class SwitchCheck implements Runnable {
@Override
public void run() {
Log.e(LOG_TAG, "***Exec Runnable***");
}
}
Here is the relevant logcat. Where the updateVisibility is called is where I left the activity.
01-13 10:28:41.941 2584-2584/com.genericappname I/Core: onEnable in ENABLING
01-13 10:28:41.941 2584-2584/com.genericappname D/Core: SDK state change from ENABLING to ENABLED
01-13 10:28:41.941 2584-3650/com.genericappname E/Core: ***Exec Runnable***
01-13 10:28:41.941 2584-3650/com.genericappname D/Core: ThisId: 0 thisExpectedId: 23
01-13 10:28:42.241 2584-2584/com.genericappname D/Core: enable ENABLED
01-13 10:28:42.251 2584-3694/com.genericappname E/Core: ***Exec Runnable***
01-13 10:28:45.491 2584-2584/com.genericappname V/ActivityThread: updateVisibility : ActivityRecord{38270d8e token=android.os.BinderProxy@177d3607 {com.genericappname/com.genericappname.Demo}} show : true
01-13 10:28:45.501 2584-2584/com.genericappname D/SRIB_DCS: log_dcs ThreadedRenderer::initialize entered!
01-13 10:28:45.501 2584-2669/com.genericappname D/mali_winsys: new_window_surface returns 0x3000, [1440x2560]-format:1
01-13 10:28:45.561 2584-2584/com.genericappname D/ViewRootImpl: changeCanvasOpacity: opaque=false
01-13 10:28:45.891 2584-2584/com.genericappname D/DEMO: onPause
01-13 10:28:45.941 2584-3650/com.genericappname E/Core: ***Exec Runnable***
01-13 10:28:45.951 2584-2584/com.genericappname D/Core: disable
01-13 10:28:45.951 2584-2584/com.genericappname D/Core: SDK state change from ENABLED to DISABLING
01-13 10:28:45.951 2584-2584/com.genericappname I/Core: onDisable
01-13 10:28:45.951 2584-2584/com.genericappname D/Core: SDK state change from DISABLING to INITIALIZED
01-13 10:28:45.951 2584-2584/com.genericappname D/Core: Exec Shutdown
01-13 10:28:46.001 2584-2584/com.genericappname I/Timeline: Timeline: Activity_idle id: android.os.BinderProxy@177d3607 time:87045589
01-13 10:28:46.011 2584-2584/com.genericappname D/DEMO: onStop
01-13 10:28:46.011 2584-2584/com.genericappname D/DEMO: onDestroy
01-13 10:28:47.941 2584-3650/com.genericappname E/Core: ***Exec Runnable***
01-13 10:28:47.941 2584-3650/com.genericappname D/Core: ThisId: 0 thisExpectedId: 23
01-13 10:28:49.941 2584-3650/com.genericappname E/Core: ***Exec Runnable***
01-13 10:28:49.941 2584-3650/com.genericappname D/Core: ThisId: 0 thisExpectedId: 23
01-13 10:28:51.941 2584-3650/com.genericappname E/Core: ***Exec Runnable***
01-13 10:28:51.941 2584-3650/com.genericappname D/Core: ThisId: 0 thisExpectedId: 23
01-13 10:28:53.941 2584-3650/com.genericappname E/Core: ***Exec Runnable***
01-13 10:28:53.941 2584-3650/com.genericappname D/Core: ThisId: 0 thisExpectedId: 23
01-13 10:28:55.941 2584-3650/com.genericappname E/Core: ***Exec Runnable***
01-13 10:28:55.941 2584-3650/com.genericappname D/Core: ThisId: 0 thisExpectedId: 23
01-13 10:28:57.951 2584-3650/com.genericappname E/Core: ***Exec Runnable***
01-13 10:28:57.951 2584-3650/com.genericappname D/Core: ThisId: 0 thisExpectedId: 23
Upvotes: 0
Views: 853
Reputation: 16059
What happens when the method is called a second time, before disable
is called :
private void enable(){
exec = new ScheduledThreadPoolExecutor(1); // Creates a NEW scheduler and takes the place of the old one. But the old one still exists and does its duty!
long period = 2000;
exec.setExecuteExistingDelayedTasksAfterShutdownPolicy(false);
exec.setContinueExistingPeriodicTasksAfterShutdownPolicy(false);
sf = exec.scheduleAtFixedRate(new SwitchCheck(), 0, period, TimeUnit.MILLISECONDS);
}
exec will point to a new Executor and the first one will go on executing the task.
You need to check if
enable
is a no-op.Upvotes: 1