2015-02-20 8 views
5

Mam zmodyfikowaną wersję przykładowej aplikacji czatu bluetooth. Skonfigurowałem ScheduledExecutorService, który wysyła polecenie na bluetooth z predefiniowaną szybkością, używając scheduleAtFixedRate.Jak zmienić stawkę lub okres powtarzającego się zadania za pomocą usługi ScheduledExecutorService?

Ustawiłem PreferenceActivity, aby umożliwić modyfikację okresu przez użytkownika. Ale nie jestem pewien, jak uzyskać aktualne powtarzające się zadania w zaktualizowanym okresie. Czy muszę jakoś anulować i ponownie uruchomić ScheduledExecutorService?

Oto odpowiednie części mojego kodu.

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

Tutaj próbowałem zaktualizować ReadInterval. Aktualizacja ReadInterval jest aktualizowana, ale powtarzający się okres polecenia nie jest aktualizowany.

@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

Spójrz na następujący post: //stackoverflow.com/questions/1519091/scheduledexecutorserser-with-variable-delay – sasankad

Odpowiedz

9

Ulepszyłem odpowiedź nieco (głównie dlatego, że ja też musiałem użyć ScheduledExecutorService). Użyj tego kodu zamiast poprzedniego, który napisałem, ponieważ poprzedni był naprawdę pod względem wydajności, bez żadnego powodu.

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

Teraz, aby przełożyć swoje zadanie podczas wykonywania, należy użyć metody changeReadInterval(time);

Będzie on odwołać poprzednią „Timer”, jeśli zostało ustawione i przełożyć nową.

+0

Dzięki, to zadziałało. – greencardigan

+0

@greencardigan Zaktualizowałem odpowiedź ulepszonym kodem. Poprzedni był dość zły i nie taki elegancki! –

+0

To wygląda lepiej. Jednak musiałem zmienić program scheduleTaskExecutor = Executors.newScheduledThreadPool (5) na zaplanowanyExecutorService = Executors.newScheduledThreadPool (5), aby go uruchomić. – greencardigan

Powiązane problemy