M-W*_*eEh 7 android coroutine kotlin kotlin-coroutines
我只是从Kotlin协程开始。我正在尝试使用协程轮询服务器,并希望在Activity或Fragment暂停时停止轮询,并相应地恢复轮询。因此,我pollScope的生命周期比所提供的生命周期短ViewModel.viewModelScope。我对目前的实施方式不完全满意,有几个问题:
pollScope?我也希望它在取消时viewModelScope也取消,这就是为什么我要指定父级作业。onResume()如果我取消pollJobs使用,为什么协程不能开始coroutineContext.cancel()?如果我保留一份工作清单并取消它们,它们会很好地启动。 import androidx.lifecycle.LifecycleOwner
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.spruce.messenger.utils.FullLifecycleObserverAdapter
import kotlinx.coroutines.*
import java.io.IOException
import java.util.concurrent.CopyOnWriteArrayList
import kotlin.coroutines.CoroutineContext
suspend fun poll(initialDelay: Long = 5000,
maxDelay: Long = 30000,
factor: Double = 2.0,
block: suspend () -> Unit) {
var currentDelay = initialDelay
while (true) {
try {
try {
block()
currentDelay = initialDelay
} catch (e: IOException) {
currentDelay = (currentDelay * factor).toLong().coerceAtMost(maxDelay)
}
delay(currentDelay)
yield()
} catch (e: CancellationException) {
break
}
}
}
class MyDataModel : ViewModel() {
val pollScope = CloseableCoroutineScope(SupervisorJob(parent = viewModelScope.coroutineContext[Job]) + Dispatchers.Main)
private val pollJobs = CopyOnWriteArrayList<Job>()
inner class CloseableCoroutineScope(context: CoroutineContext) : FullLifecycleObserverAdapter(), CoroutineScope {
override val coroutineContext: CoroutineContext = context
override fun onPause(owner: LifecycleOwner) {
super.onPause(owner)
// coroutineContext.cancel() // this cancels it but then coroutine doesn't start again in onResume()
pollJobs.forEach { it.cancel() }
}
override fun onResume(owner: LifecycleOwner) {
super.onResume(owner)
refresh()
}
}
fun refresh() {
if (pollJobs.count { it.isActive } == 0) {
startPoll()
}
}
private fun startPoll() = pollScope.launch {
try {
poll {
//fetch data from server
}
} catch (e: Exception) {
//ignore
}
}.also {
track(it)
}
private fun track(job: Job) {
pollJobs.add(job)
job.invokeOnCompletion {
pollJobs.remove(job)
}
}
}
Run Code Online (Sandbox Code Playgroud)
然后在我的片段中,将pollScope添加为生命周期观察器viewLifecycleOwner.lifecycle.addObserver(viewModel.pollScope)。
你pollScope对我来说似乎很好。
当您取消某个 时Job,它会取消该 的所有协程Job。
我会使用 aViewModel和 a CoroutineScope,然后从中进行轮询。确保Job在虚拟机终止时管理我的协程并取消我的协程。
class MyViewModel() : ViewModel(),
CoroutineScope by CoroutineScope(Dispatchers.Main + SupervisorJob()) {
// ...
override fun onCleared() {
cancel()
super.onCleared()
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
296 次 |
| 最近记录: |