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