2016-01-13 5 views
0

У меня есть библиотека Android, у которой есть ScheduledThreadPoolExecutor. Он выполняет задачу каждые две секунды для проверки состояния и запускается, когда приложение вызывает функцию enable() библиотеки. Когда приложение вызывает функцию disable(), которая затем отменяет задачу ScheduledFuture и вызывает shutdownNow() для исполнителя. Проблема в том, что она не останавливается. В журналах для приложения я вижу, как вызывается функция disable() и видят, где выполняется Exec Shutdown, но я все еще вижу сообщение Exec Runnable, запущенное в фоновом режиме. Фактически, он продолжает работать, пока я не убью приложение. Любые идеи, почему задача не останавливается? Соответствующий код:My ScheduledThreadPoolExecutor не закрывается

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***"); 

    } 
} 

Вот соответствующий логарифм. Там, где вызывается updateVisibility, я оставил действие.

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 [email protected] {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: [email protected] 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 
+0

Таким образом, он продолжает размножать потоки каждые 2 секунды? –

+0

Не могли бы вы добавить вывод logcat? С первого взгляда выглядит на первый взгляд. – Fildor

+0

Есть ли вероятность, что вы видите журналы ранее незавершенных потоков? Даже если вы вызываете disable, в очереди могут быть запланированные задания. –

ответ

1

Что происходит, когда метод называется второй раз, перед тем disable называется:

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 будет указывать на новый Исполнителю и первый будет идти на выполнение задачи.

Вы должны проверить, если

  1. Вы уже Исполнителю, который еще не был отключен.
  2. У вас уже есть расписание задач на нем. И если да, то enable - это не-опера.
+0

В полной функции, если разрешение вызывается дважды, логическая проверка пропускает настройку нового Исполнителя. Я просто не включил эту логику в этот пример. – Frackinfrell