如何安排随机时间(每隔随机分钟)事件

How to schedule a random timing (every random minutes) event

我正在开发 Android 应用程序,我正在尝试管理振动事件。 当检查开关时,我需要每隔几分钟安排一次。我一直在使用这个代码:

int delay3 = (60 + new Random().nextInt(60)) * 1000;

timer3.schedule(timerTask3, 0, delay3);

但计时器不会更改 delay3,直到取消选中开关并再次选中。有没有办法在随机时间安排事件,即 delay3 应该在每次任务 运行 时更改而不取消选中开关?

谢谢。

随机延迟一次后将任务安排到运行。在任务内部,在期望的过程之后,随机延迟后重新安排它。

示例:

Random random = new Random();
Timer timer = new Timer();
timer.schedule(new MyTimerTask(timer, random), random.nextInt(10000));

与:

private static class MyTimerTask extends TimerTask {
    private final Timer timer;
    private final Random random;

    public MyTimerTask(Timer timer, Random random) {
        this.timer = timer;
        this.random = random;
    }

    @Override
    public void run() {
        System.out.println("TEST");
        timer.schedule(new MyTimerTask(timer, random), random.nextInt(10000));
    }
}

你也可以使用android.os.Handlerclass的postDelayed方法代替 scheduleAtFixedRate java.util.Timer 方法 class.

只需创建 android.os.Handler class 的实例并调用 android.os.Handler 实例的 postDelayed 方法,而不是创建 java.util.Timer class 并调用 java.util.Timer 实例的 scheduleAtFixedRate 方法。

请注意,您必须将 TimerTask 接口替换为 Runnable 接口。

Runnable 实例的 run 方法结束时(作为第一个参数传递给 android.os.Handler 实例的 postDelayed 方法)用 new 再次调用随机延迟相同 android.os.Handler 实例的 postDelayed 方法与 相同 Runnable 实例!

无需创建 TimerTask 的新实例,也无需创建 Runnable 的新实例!

这样效率更高,因为在堆内存上分配的对象较少,因此垃圾收集器不会忙于通过这种方式从堆内存中释放对象!

有一个我用自己的想法自己写的demo:

import android.os.Handler;
import java.util.Random;

public class Demo
{
   private boolean postAgain;
   public void start()
   {
       postAgain = true;
       final Handler handler = new Handler();
       final Random random = new Random();
       final Runnable runnable = () ->
       { 
           log.d("Hello");
           if (postAgain)
           {
               handler.postDelayed(runnable,random.nextInt(10000));
           }
       };
       handler.postDelayed(runnable,random.nextInt(10000));
   }

   public void stop() { postAgain = false; }

请注意,上面的代码使用了 Java 8 个 lambda 表达式。 在 Java 7 及以下版本中,您可以创建一个 Runnable 接口的实例来实现 run 方法,而无需定义一个新的命名 class 来实现 Runnable 界面。

另请注意,start 方法的所有局部变量必须全部为 final,以便能够在 lambda 表达式或 run 方法中使用它们Runnable实例。

调用start方法以随机延迟重复打印"Hello"并调用stop方法来停止它。

请注意,stop 方法仅将 boolean 字段从 true 设置为 false 以停止循环。