几组概念:
suspend--resume
invoke(call)--return
launch返回Job
async返回Deferred implement Job
CoroutineScope 和生命周期协同,如lifecycleScope,viewModelScope
CoroutineContext =Job+CoroutineDispatcher
翻译:
使用Jetpackd viewModelScope或者lifecycleScope 他们已经帮我们处理了生命周期事件。
如果我们自己使用CoroutineScope,那么需要自己处理activity/fragment/lifecycle生命周期事件,在结束时cancel()。
如果我们希望离开当前生命周期view,我们的CoroutineScope继续执行。
1,如果进程被杀死,依然希望执行我们的计划,那么可以使用WorkManager。
2,如果希望在进程存在的场景下,可以使用CoroutineScope.
CoroutineScope最佳实践:
1,CoroutineDispatcher 不应该写死,应该是可以被替换的。
2,mvp/mvvm应该在p层,vm层创建coroutines,主要目的是避免view和业务产生关联。另一个情况是,如果实在需要在view层创建协程,可行的做法是vm或者p层提供挂起方法(suspend)
3,vm、p层之下的层(如repository层)要暴露suspend function或者Flows。主要目的是为了生命周期管理。
如果有高优先级的操作不能让coroutine暂停,怎么做?
1,那么需要在Application中创建scope,然后把这些操作放到这个scope中启动,再把这个scope注入到使用的类中。注意:这种做法和使用GlobalScope有些不同,就是你可以在CoroutineContext中自己控制CoroutineDispatcher,CoroutineExceptionHandler.
2,这个applicationScope必须包含:SupervisorJob():他不会把失败传递给进程。
3,val applicationScope = CoroutineScope(SupervisorJob()+otherDonfig)
如果期望携程返回结果,那么使用async并调用await得到异步结果;
return externalScope.async{
//do important thing
}.await()
如果不需要结果,则使用launch,使用join并等待执行结束;:
externalScope.launch{
//do important thing
}.join()
或者使用:
withContext(externalScope.coroutineContext){
//do important thing
}
注意点:
1,如果携程被cancelled,但是//do important thing正在执行,那么携程不会在//do important thing结束是结束,而是在下一个cancellation点到的时候再cancell。
2,使用withContext时,携程的ExceptionHandler不会工作,知道异常被抛出。