JobScheduler-如何跳过定期作业的首次作业? [英] JobScheduler - How to skip first job run of periodic job?

查看:79
本文介绍了JobScheduler-如何跳过定期作业的首次作业?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在我的应用程序中,我设置了一个定期作业,该作业设置为每30分钟运行一次.当我确实安排该定期作业时,第一次作业运行就发生了,对于我而言,这是我所不希望的.我要跳过的是第一次运行,这样它将在30分钟以上后第一次运行.

in my app i have set a periodic job that is set to run every 30 minutes. The first job run occurs right when I do schedule that periodic job, which is not wanted in my case. What I want is to skip the first run so that it will run for the first time after 30+ minutes.

我对如何解决此问题的两种想法是要么使它在最初的30分钟内根本不运行(某种程度的延迟),要么将第一个作业标记为已完成,甚至没有机会开始.不幸的是,我没有在 JobInfo 中找到任何允许我做的任何方法.

My two thoughts on how to approach this was to either have it not run at all for the first 30 minutes somehow (some kind of delay), or mark the first job run as done before even having the chance to start. Unfortunately I have not found any method in JobInfo that would allow me to do any of those.

另一个可以满足我需要的解决方法是以某种方式将作业限制为仅在应用程序在后台运行.它不能完全解决问题,但可以作为我的解决方法.

Another workaround that would fulfill my needs would be to somehow limit the jobs to only occur while app is in the background. It does not entirely solve the issue but it could serve as a workaround in my case.

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

Following is my current code for scheduling the periodic job:

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);
}

我希望有人遇到同样的情况并能帮助我解决问题...谢谢!

I hope someone has run into the same situation and can help me resolve it... Thank you!

推荐答案

使用 WorkManager 安排背景工作,请参见简介此处.

Use WorkManager for scheduling backgound work, see introduction here.

1.添加依赖项:

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

2.创建工人类别:

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 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>

这篇关于JobScheduler-如何跳过定期作业的首次作业?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆