如何安排定期后台工作在固定时间激活?

How to schedule a periodic background work to activate at fixed times?

我想在固定时间每 12 小时推送一次通知(例如,每天上午 9 点和晚上 9 点)。这是我当前的 doWork() 代码:

  @NonNull
    @Override
    public Result doWork() {

        database.child("business_users").child(currentUserID).addValueEventListener(new ValueEventListener() {
            @Override
            public void onDataChange(@NonNull DataSnapshot snapshot) {
                user = snapshot.getValue(BusinessUser.class);
                if(user.isNotifications()==true)
                {
                    if(user.getRatingsCount() > user.getLastKnownRC())
                    {
                        theDifference = user.getRatingsCount() - user.getLastKnownRC();
                        notification();
                    }
                }

            }

            @Override
            public void onCancelled(@NonNull DatabaseError error) {

            }
        });

        Log.i("BackgroundWork" , "notif sent");
        return Result.success();
    }

`

这是作品创作代码:

public void FirstTimeWork ()
     {
         PeriodicWorkRequest myWorkRequest =
                 new PeriodicWorkRequest.Builder(BackgroundWork.class, 12, TimeUnit.HOURS)
                         .setInitialDelay(1, TimeUnit.DAYS)
                         .addTag("notif")
                         .build();
     }

我看到有人用日历来做,但我不明白它是如何工作的。

@EnableScheduling 注释用于为您的应用程序启用调度程序。此注释应添加到主 Spring 引导应用程序 class 文件中。

@SpringBootApplication
@EnableScheduling
public class DemoApplication {
   public static void main(String[] args) {
      SpringApplication.run(DemoApplication.class, args);
   }
}

@Scheduled 注解用于触发特定时间段的调度程序。

@Scheduled(cron = "0 * 9 * * ?")
public void cronJobSch() throws Exception {
}

以下示例代码展示了如何在每天

上午 9:00 上午 9:59 上午每分钟执行一次任务
package com.tutorialspoint.demo.scheduler;

import java.text.SimpleDateFormat;
import java.util.Date;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

@Component
public class Scheduler {
   @Scheduled(cron = "0 * 9 * * ?")
   public void cronJobSch() {
      System.out.println(LocalDateTime.now());
   }
}

您可以使用 class Timer。然后,您的后台作业必须在覆盖方法 public void run() 中的子 class 到 TimerTask 中实现,例如:

public class BackgroundWork extends TimerTask {
    @Override
    public void run() {
        // Do your background work here
        Log.i("BackgroundWork" , "notif sent");
    }
}

您可以按如下方式安排此工作:

// void scheduleAtFixedRate(TimerTask task, Date firstTime, long period)
Date date = new Date( 122, 04, 02, 9, 00 );
(new Timer()).scheduleAtFixedRate(new BackgroundWork(), date, 43200000L);

定时器启动一个新线程来执行这个作业。如有必要,您可以取消它。

我找到了一个简单的解决方案,使用日历:

calendar.setTimeInMillis(System.currentTimeMillis());
calendar.set(Calendar.HOUR_OF_DAY, 22);
calendar.set(Calendar.MINUTE, 0);
calendar.set(Calendar.SECOND, 0);
calendar.set(Calendar.MILLISECOND, 0);

if (calendar.getTimeInMillis() <= System.currentTimeMillis()) {
    calendar.set(Calendar.DAY_OF_MONTH, Calendar.DAY_OF_MONTH + 1);
}

初始延迟设置如下:

.setInitialDelay(calendar.getTimeInMillis() - System.currentTimeMillis(), TimeUnit.MILLISECONDS)

这似乎运作良好。

使用 ScheduledExecutorService

        ScheduledExecutorService scheduledExecutorService
                = Executors.newScheduledThreadPool(CORE_POOL_SIZE);

        // Calculate initial day based on the current time
        Long initalDelay = 0l;

        ScheduledFuture<?> scheduledFuture =
                scheduledExecutorService.scheduleAtFixedRate(doWork(), initalDelay, 12l, TimeUnit.HOURS);