【问题标题】:Android Work Manager: How to enqueue Jobs once a monthAndroid Work Manager:如何每月将作业排入队列
【发布时间】:2019-05-22 21:27:01
【问题描述】:

this question 之后,我查看了 Android 作业调度,如果我想每个月做一次事情,工作管理器似乎是最新的工具。我构建了一个 Worker 类并在我的活动中使用这个 sn-p 激活它:

PeriodicWorkRequest myWorkRequest =
                new PeriodicWorkRequest.Builder(MonthlyWorker.class, 20, TimeUnit.MINUTES)
                        .build();
WorkManager.getInstance().enqueueUniquePeriodicWork("my fancy test",ExistingPeriodicWorkPolicy.KEEP, myWorkRequest);

虽然我成功地测试了 20 分钟的时间段,但存在一个问题:几个月没有可用的时间单位,只有几天。由于显而易见的原因,每 30 天做一次工作是行不通的,因为我需要在每个月的第一天执行任务。所以我该怎么做?我必须使用不同的 API 吗?谢谢。

我可以做类似if (dayOfMonth==1) do Function 的事情,但我认为这会破坏调度程序的目的。

【问题讨论】:

    标签: android android-workmanager periodic-task timeunit


    【解决方案1】:

    您可以自己按分钟完成:

    只需将天转换为分钟:

    这里:30 天 = 43200 分钟 = 1 个月

    PeriodicWorkRequest myWorkRequest =
                new PeriodicWorkRequest.Builder(MonthlyWorker.class, 43200, TimeUnit.MINUTES)
                        .build();
    WorkManager.getInstance().enqueueUniquePeriodicWork("my fancy test",ExistingPeriodicWorkPolicy.KEEP, myWorkRequest);
    

    更新:

    根据我的要求,我想在上午 8 点到下午 6 点之间每 30 分钟执行一次任务

    在我为您制作的那个工人的帮助下,您需要每个月的 1 日凌晨 12 点到凌晨 2 点如下:

    public class TestWorker extends Worker {
    
        private static final String DEFAULT_START_TIME = "00:01"; //12:01 am
        private static final String DEFAULT_END_TIME = "03:00"; // 03:00 am
    
        private static final String TAG = "TestWorker";
    
        public TestWorker(@NonNull Context context, @NonNull WorkerParameters workerParams) {
            super(context, workerParams);
        }
    
        @NonNull
        @Override
        public Result doWork() {
    
            /**
             * Its for time
             */
            DateFormat dateFormat = new SimpleDateFormat("HH:mm", Locale.getDefault());
    
            /**
             * Get Current Calendar Instance
             */
            Calendar c = Calendar.getInstance();
    
            // Get current day of month
            int day = c.get(Calendar.DAY_OF_MONTH);
    
            /**
             * Get current time and compare with our start and end date.
             */
            Date date = c.getTime();
            String formattedDate = dateFormat.format(date);
    
            try {
                Date currentDate = dateFormat.parse(formattedDate);
                Date startDate = dateFormat.parse(DEFAULT_START_TIME);
                Date endDate = dateFormat.parse(DEFAULT_END_TIME);
    
                /**
                 * This condition will check that day is 1, and time interval in between give time.
                 */         
                if (day == 1 && currentDate.after(startDate) && currentDate.before(endDate)) {
                    // Do your work here
                }
            } catch (ParseException ignored) {
    
            }
    
            return Result.success();
        }
    }
    

    您可以每隔 X 小时开始此测试工作,以便每隔 X 小时检查一次(例如,在您的情况下,您可以给 2 小时,以便每隔两小时检查一次)

    不知道会不会影响性能,但我觉得没有其他解决办法。

    你可以像下面这样启动worker:

    PeriodicWorkRequest periodicWork = new PeriodicWorkRequest.Builder(MyWorker.class, 2, TimeUnit.HOURS)
                    .addTag("MYWORK")
                    .build();
    
    WorkManager.getInstance().enqueueUniquePeriodicWork("MYWORK", ExistingPeriodicWorkPolicy.REPLACE, periodicWork);
    

    希望它会有所帮助。

    【讨论】:

    • 谢谢,但不是每个月都有 30 天。
    • 你想要在任何特定日期吗?
    • 是的,每个月的第一天。抱歉,如果问题不够具体。
    • 以及每个月 1 日的具体时间?
    • 最好在一天的开始,午夜之后。
    【解决方案2】:

    也许您可以创建一个 WorkManager 并检查今天是否是一个月中的第一天,如下所示:

    Calendar c = Calendar.getInstance();
    c.add(Calendar.MONTH, 0);
    c.set(Calendar.DAY_OF_MONTH, 1);
    String monthfirst = format.format(c.getTime());
    System.out.println("===============nowfirst:" + monthfirst);
    

    如果是真的,你可以做一份真正的工作。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-10-18
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多