如何使用 ScheduledExecutorService 更改重复任务的速率或周期? [复制]

Posted

技术标签:

【中文标题】如何使用 ScheduledExecutorService 更改重复任务的速率或周期? [复制]【英文标题】:How do I change the rate or period of a repeating task using ScheduledExecutorService? [duplicate] 【发布时间】:2015-04-21 15:35:18 【问题描述】:

我有一个蓝牙聊天示例应用的修改版本。我设置了一个ScheduledExecutorService,它使用scheduleAtFixedRate以预定义的速率通过蓝牙发送命令。

我已设置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);      
    

我试图在这里更新ReadIntervalReadInterval 正在更新,但循环命令周期未更新。

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

【问题讨论】:

看下面的帖子http://***.com/questions/1519091/scheduledexecutorservice-with-variable-delay 【参考方案1】:

我稍微改进了答案(主要是因为我也不得不使用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);

如果已设置,它将取消先前的“计时器”并重新安排一个新的。

【讨论】:

谢谢,这已经奏效了。 @greencardigan 我用改进的代码更新了答案。前一个很糟糕,没有那么优雅! 这看起来更好。但是,我必须将 scheduleTaskExecutor = Executors.newScheduledThreadPool(5) 更改为 scheduleExecutorService = Executors.newScheduledThreadPool(5) 才能让它工作。 不要忘记 scheduledExecutorService.setRemoveOnCancelPolicy(true) 以防止内存泄漏(参见例如***.com/a/23370049/1052284)

以上是关于如何使用 ScheduledExecutorService 更改重复任务的速率或周期? [复制]的主要内容,如果未能解决你的问题,请参考以下文章

[精选] Mysql分表与分库如何拆分,如何设计,如何使用

如果加入条件,我该如何解决。如果使用字符串连接,我如何使用

如何使用本机反应创建登录以及如何验证会话

如何在自动布局中使用约束标识符以及如何使用标识符更改约束? [迅速]

如何使用 AngularJS 的 ng-model 创建一个数组以及如何使用 jquery 提交?

如何使用laravel保存所有行数据每个行名或相等