2015-02-20 2 views
5

У меня есть модифицированная версия приложения для чата bluetooth. Я установил ScheduledExecutorService, который отправляет команду по bluetooth с предопределенной скоростью, используя scheduleAtFixedRate.Как изменить скорость или период повторяющейся задачи с помощью функции ScheduledExecutorService?

Я установил PreferenceActivity, чтобы разрешить период, который будет изменен пользователем. Но я не уверен, как получить текущие повторяющиеся задачи с обновленным периодом. Нужно ли мне отменить и перезапустить ScheduledExecutorService?

Вот часть моего кода.

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);  
    } 

И я пытался обновить ReadInterval здесь. ReadInterval обновляется, но период повторяющейся команды не обновляется.

@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"); 
    } 
} 
+0

смотрите следующее сообщение: //stackoverflow.com/questions/1519091/scheduledexecutorservice-with-variable-delay – sasankad

ответ

9

Я немного улучшил ответ (в основном потому, что мне тоже пришлось использовать ScheduledExecutorService). Пожалуйста, используйте этот код вместо предыдущего, который я опубликовал, потому что предыдущий был действительно по производительности, без уважительной причины.

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); 
    } 
} 

Теперь, чтобы перенести свою задачу во время выполнения, используйте метод changeReadInterval(time);

Это отменит предыдущий «таймер», если он установлен и перепланировать новый.

+0

Спасибо, это сработало. – greencardigan

+0

@greencardigan Я обновил ответ с помощью улучшенного кода. Предыдущий был довольно плохим и не очень элегантным! –

+0

Это выглядит лучше. Однако мне пришлось изменить scheduleTaskExecutor = Executors.newScheduledThreadPool (5) на scheduleExecutorService = Executors.newScheduledThreadPool (5), чтобы заставить его работать. – greencardigan