JobScheduler - 如何跳过定期作业的第一份工作 运行?

JobScheduler - How to skip first job run of periodic job?

在我的应用程序中,我设置了一个定期作业,该作业设置为每 30 分钟 运行。 第一份工作 运行 就在我安排定期工作时发生,这在我的情况下是不需要的。 我想要的是跳过第一个 运行,这样它将在 30 多分钟后第一次 运行。

我关于如何处理这个问题的两个想法是要么在前 30 分钟内完全不 运行 以某种方式(某种延迟),要么将第一份工作 运行 标记为甚至在有机会开始之前就完成了。 不幸的是,我没有在 JobInfo 中找到任何允许我执行这些操作的方法。

另一种可以满足我需求的解决方法是以某种方式限制作业仅在应用程序处于后台时发生。它并不能完全解决问题,但可以作为我的解决方法。

以下是我当前用于安排定期作业的代码:

private void scheduleJob() {
    ComponentName componentName = new ComponentName(this, myRecurringTask.class);
    JobInfo info = new JobInfo.Builder(JOB_ID, componentName)
            .setRequiredNetworkType(JobInfo.NETWORK_TYPE_ANY)
            .setPersisted(true)
            .setPeriodic(1800000)
            .build();
    JobScheduler scheduler = (JobScheduler) getSystemService(JOB_SCHEDULER_SERVICE);
    scheduler.schedule(info);
}

希望有人运行遇到同样的情况,可以帮我解决...谢谢!

使用 WorkManager 安排后台工作,请参阅介绍 here

1.添加依赖项:

implementation "androidx.work:work-runtime-ktx:2.4.0"

2。创建工人 Class:

class DataRefresher(context: Context, params: WorkerParameters) : CoroutineWorker(context, params) {
    override suspend fun doWork(): Result {                 //will run on background thread
        //your logic

        return try {
            //your logic

            Result.success()
        } catch (e: HttpException) {
            Result.retry()
        }
    }
}

3。创建应用程序 Class:

class DevBytesApplication : Application() {
    private val backgroundScope = CoroutineScope(Dispatchers.Default)       //standard background thread

    override fun onCreate() {                           //called when app launches, same as Activity
        super.onCreate()

        initWork()
    }

    private fun initWork() {
        backgroundScope.launch {                        //run in background, not affecting ui
            setupDataRefreshingWork()
        }
    }

    @SuppressLint("IdleBatteryChargingConstraints")
    private fun setupDataRefreshingWork() {
        val constraints = Constraints.Builder()
            .setRequiredNetworkType(NetworkType.UNMETERED)          //when using wifi
            .setRequiresBatteryNotLow(true)
            .setRequiresCharging(true)
            .setRequiresDeviceIdle(true)                    //when not running heavy task
            .build()

        val repeatingRequest = PeriodicWorkRequestBuilder<DataRefresher>(1, TimeUnit.DAYS)      //【15 minutes is minimum!!】
            .setConstraints(constraints)
            .setInitialDelay(30, TimeUnit.MINUTES)        //【initial delay!!】
            .build()

        WorkManager.getInstance(this).enqueueUniquePeriodicWork(
            DataRefresher::class.java.simpleName,               //work name
            ExistingPeriodicWorkPolicy.KEEP,                    //if new work comes in with same name, discard it
            repeatingRequest
        )
    }
}

4.设置 AndroidManifest:

<manifest
    xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.devbytestest">

    <application
        android:name=".DevBytesApplication"                 //【here, must!!!】
    
        ...

    </application>

</manifest>