继续记录Kotlin的协程,上次封装了CoroutineScope ,现在就是如何控制退出呢,比如我启动一个任务后,我界面要消失了,因此任务也要取消。
简单记录于此,方便自己查阅。
流水文二,勿喷。
正文
接上文《》中AppScope
object AppScope : CoroutineScope { override val coroutineContext = SupervisorJob() + Dispatchers.Default }
⚠️ 注意:必须是
SupervisorJob(),否则一个任务 cancel,全部跟着死。
下面简单的展示如何取消任务。
var job = AppScope.launch { delay(1000) Log.d(TAG, "onResume 1 : delay 1000 " + Thread.currentThread().name) } job.cancel("MainActivity onResume")
统一管理job
方式 1
启动任务并持有
class UploadManager { // 保存单个任务 private val uploadJob: Job? = null fun startUpload() { val job = AppScope.launch { //耗时操作 } uploadJob = job } fun stopUpload() { uploadJob?.cancel("User cancel upload") uploadJob = null } }
只取消上传任务
不影响 AppScope 其他任务
方式2
object TaskManager { private val tasks = ConcurrentHashMap<String, Job>() fun launchTask( name: String, block: suspend CoroutineScope.() -> Unit ): Job { val job = AppScope.launch(block = block) tasks[name] = job job.invokeOnCompletion { tasks.remove(name) } return job } fun cancelTask(name: String) { tasks[name]?.cancel("Task $name cancelled") } fun cancelAll() { tasks.values.forEach { it.cancel() } tasks.clear() } }
使用
TaskManager.launchTask("sync") { while (true) { delay(2000) Log.d("Sync", "syncing...") } } // 取消指定任务 TaskManager.cancelTask("sync")
这是 SDK / 后台任务 / 长连接管理 的标准做法。
小结
AppScope 本身不能也不应该“按任务取消”
每个任务自己持有 Job,用 Job.cancel()
也就是取消任务似乎通过Job的!
AppScope的职责只有一个:App 进程活着,它就活着;App 死了,它全 cancel
参考文章
AI
《

