2015-02-20 4 views
5

Ich habe eine modifizierte Version der Bluetooth-Chat-Beispiel-App. Ich habe eine ScheduledExecutorService eingerichtet, die einen Befehl über Bluetooth mit einer vordefinierten Rate sendet mit scheduleAtFixedRate.Wie ändere ich die Rate oder den Zeitraum einer sich wiederholenden Aufgabe mit ScheduledExecutorService?

Ich habe eine PreferenceActivity eingerichtet, damit der Zeitraum vom Benutzer geändert werden kann. Aber ich bin mir nicht sicher, wie die eigentlichen wiederkehrenden Aufgaben mit dem aktualisierten Zeitraum durchgeführt werden. Muss ich die ScheduledExecutorService irgendwie abbrechen und neu starten?

Hier sind die relevanten Teile meines Codes.

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

Und ich habe versucht, ReadInterval hier zu aktualisieren. Die ReadInterval wird aktualisiert, aber die wiederkehrende Befehlsperiode wird nicht aktualisiert.

@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

betrachten Sie die folgenden postthttp: //stackoverflow.com/questions/1519091/scheduledexecutorservice-with-variable-delay – sasankad

Antwort

9

Ich verbesserte die Antwort ein wenig (hauptsächlich weil ich auch ScheduledExecutorService verwenden musste). Bitte benutze diesen Code anstelle des vorherigen, den ich gepostet habe, weil der vorherige wirklich aus Performancegründen war.

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

nun Ihre Aufgabe während der Laufzeit neu zu berechnen, verwenden Sie die Methode changeReadInterval(time);

Es wird die vorherige „Timer“ abbrechen, wenn es eine neue eingestellt wurde und wird neu planen.

+0

Danke, das hat funktioniert. – greencardigan

+0

@greencardigan Ich habe die Antwort mit verbessertem Code aktualisiert. Der vorherige war ziemlich schlecht und nicht so elegant! –

+0

Das sieht besser aus. Allerdings musste ich scheduleTaskExecutor = Executors.newScheduledThreadPool (5) in "planedExecutorService = Executors.newScheduledThreadPool (5)" ändern, damit es funktioniert. – greencardigan

Verwandte Themen