Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/kotlin/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android 重复协同工作程序_Android_Kotlin - Fatal编程技术网

Android 重复协同工作程序

Android 重复协同工作程序,android,kotlin,Android,Kotlin,我有一个协同程序工作人员,希望每隔1分钟定期给我打电话。你将如何继续这样做 我的工人看起来像这样: class CloudDataWorker(context: Context, params: WorkerParameters): CoroutineWorker(context, params) { companion object { const val WORK_NAME = "CloudDataWorker" } o

我有一个协同程序工作人员,希望每隔1分钟定期给我打电话。你将如何继续这样做

我的工人看起来像这样:

class CloudDataWorker(context: Context, params: WorkerParameters):
    CoroutineWorker(context, params) {

    companion object {
        const val WORK_NAME = "CloudDataWorker"
    }

    override suspend fun doWork(): Result {
        Timber.d("Background worker started.")

        val repository = Repository(applicationContext);

        return try {
            if(repository.getAllJobs().hasActiveObservers()){
                Timber.d("Found active listeners on cloud data.")
                repository.refreshJobs()
            } else {
                Timber.d("No active listeners for cloud data found.")
            }

            Result.success()

        } catch (e: HttpException) {
            Timber.e("Error during update of cloud data: ${e.message()}")
            Result.retry()
        }
    }
}

好的,我们的想法是使用一次性请求(具有初始延迟)来设置工作,并使用
observeforver()
来重新设置工作

以下是每5秒显示一条
Toast
消息的示例:

private val backgroundScope = CoroutineScope(Dispatchers.Default)    //standard background thread

private fun initWork() {
    backgroundScope.launch {      //setup work in background thread
        setupToastShowingWork(0)  //no delay at first time

        observeToastShowingWork() //observe work state changes
    }
}

private fun setupToastShowingWork(delayInSeconds: Long) {    //must run in background thread
    val constraints = Constraints.Builder().run {
        setRequiredNetworkType(NetworkType.UNMETERED)    //when using WiFi
        build()
    }

    val oneTimeRequest = OneTimeWorkRequestBuilder<ToastShower>().run { //【for breaking 15 minutes limit we have to use one time request】
        setInitialDelay(delayInSeconds, TimeUnit.SECONDS)    //customizable delay (interval) time
        setConstraints(constraints)
        build()
    }

    WorkManager.getInstance(applicationContext).enqueueUniqueWork(    //【must be unique!!】
        ToastShower::class.java.simpleName,    //work name, use class name for convenient
        ExistingWorkPolicy.KEEP,    //if new work comes in with same name, discard the new one
        oneTimeRequest
    )
}

private suspend fun observeToastShowingWork() {
    withContext(Dispatchers.Main) {    //【must run in Main thread!!】 See below
        WorkManager.getInstance(applicationContext).getWorkInfosForUniqueWorkLiveData(ToastShower::class.java.simpleName).observeForever {
            if (it[0].state == WorkInfo.State.SUCCEEDED) {    //when the work is done
                backgroundScope.launch {    //prevent from running in Main thread
                    setupToastShowingWork(5)    //every 5 seconds
                }
            }
        }
    }
}
private val backgroundScope=CoroutineScope(Dispatchers.Default)//标准后台线程
私人娱乐工作(){
backgroundScope.launch{//后台线程中的设置工作
setupToastShowingWork(0)//第一次没有延迟
observeToastShowingWork()//观察工作状态更改
}
}
私人娱乐设置到展示工作(delayUnseconds:Long){//必须在后台线程中运行
val constraints=constraints.Builder().run{
setRequiredNetworkType(NetworkType.UNMETERED)//使用WiFi时
构建()
}
val oneTimeRequest=OneTimeWorkRequestBuilder()。运行{/[为了打破15分钟的限制,我们必须使用一次请求]
setInitialDelay(delayInSeconds,TimeUnit.SECONDS)//可自定义的延迟(间隔)时间
设置约束(约束)
构建()
}
WorkManager.getInstance(applicationContext).enqueueUniqueWork(/[必须是唯一的!!]
ToastShower::class.java.simpleName,//工作名,使用类名方便
ExistingWorkPolicy.KEEP,//如果新工作具有相同的名称,则放弃新工作
一次性请求
)
}
私人娱乐观看表演作品(){
withContext(Dispatchers.Main){/[必须在主线程中运行!!]见下文
WorkManager.getInstance(applicationContext).getWorkInfo运行IQueWorkLiveData(ToastShower::class.java.simpleName).observeForver{
如果(它[0].state==WorkInfo.state.successed){//当工作完成时
backgroundScope.launch{//防止在主线程中运行
设置为显示工作(5)//每5秒
}
}
}
}
}
演示:


有益阅读:


    • 你不能。
      周期性工作的最小运行间隔为15分钟

      如果你的应用程序在前台,我建议你使用循环和协同程序,并利用
      Kotlin流

      class YourViewModel(val repo: YourRepo) : ViewModel() {
      
          val yourJobOffers = 
              flow {
                  while(true) {
                      emit(repo.fetchJobs())
                      delay(1000 * 60)
                  }
              }
              .launchIn(Dispatchers.IO)
      }