一个异步编程的框架
1、怎么去用?
GlobalScope.launch和runBlocking,前者不阻塞,后者会阻塞。
//从上面运行结果可以看出,通过CoroutineScope.launch开启一个协程,协程体里的任务时就会先挂起(suspend),
// 让CoroutineScope.launch后面的代码继续执行,直到协程体内的方法执行完成再自动切回来所在的上下文回调结果。
//!!!所以launch是最后执行的
Log.e(TAG,"2.BtnClick1.... [当前线程为:${Thread.currentThread().name}]")
CoroutineScope(Dispatchers.Main).launch{
Log.e(TAG,"1.执行CoroutineScope?????????.... [当前线程为:${Thread.currentThread().name}]")
delay(2000)
Log.e(TAG,"1.执行CoroutineScope.... [当前线程为:${Thread.currentThread().name}]")
}
Log.e(TAG,"2.BtnClick1.... [当前线程为:${Thread.currentThread().name}]")
//!!!runBlocking是最后执行的
//runBlocking里的任务如果是非常耗时的操作时,会一直阻塞当前线程,在实际开发中很少会用到runBlocking
runBlocking {
delay(2000)
Log.e(TAG,"1.runBlocking.... [当前线程为:${Thread.currentThread().name}]")
}
Log.e(TAG,"2.BtnClick2.... [当前线程为:${Thread.currentThread().name}]")
//withContext 与 async 它们能获得返回值
2、GlobalScope里边跑两个 能得到返回值
2.1withContext 串行执行的
// 串行执行
GlobalScope.launch {
val task1 = withContext(Dispatchers.IO){
delay(1000)
Log.e(TAG, "go: ", )
}
val task2 = withContext(Dispatchers.IO){
delay(1000)
Log.e(TAG, "go2: ", )
}
Log.e("TAG", "task1 = $task1 , task2 = $task2 ,")
}
2.2 async是并行执行的,如果要在得到两个async的结果的话 ,可以用await
GlobalScope.launch {
//并行执行,但是有个await,所以会等到都好了
val task1 = async(Dispatchers.IO) {
delay(2000)
Log.e("TAG", "1.执行task1.... [当前线程为:${Thread.currentThread().name}]")
"one" //返回结果赋值给task1
}
val task2 = async(Dispatchers.IO) {
delay(1000)
Log.e("TAG", "2.执行task2.... [当前线程为:${Thread.currentThread().name}]")
"two" //返回结果赋值给task2
}
Log.e("TAG", "task1 = ${task1.await()} , task2 = ${task2.await()} , 耗时 [当前线程为:${Thread.currentThread().name}]")
}
2.3 async(){}.wait()变回串行
//变回串行
//await() 只有在 async 未执行完成返回结果时,才会挂起协程。
// 若 async 已经有结果了,await() 则直接获取其结果并赋值给变量,此时不会挂起协程。
CoroutineScope(Dispatchers.Main).launch {
val time1 = System.currentTimeMillis()
val task1 = async(Dispatchers.IO) {
delay(2000)
Log.e("TAG", "1.执行task1.... [当前线程为:${Thread.currentThread().name}]")
"one" //返回结果赋值给task1
}.await()
val task2 = async(Dispatchers.IO) {
delay(1000)
Log.e("TAG", "2.执行task2.... [当前线程为:${Thread.currentThread().name}]")
"two" //返回结果赋值给task2
}.await()
Log.e("TAG", "task1 = $task1 , task2 = $task2 , 耗时 ${System.currentTimeMillis() - time1} ms [当前线程为:${Thread.currentThread().name}]")
}
2.4、doAsync
// 还有个Async 整个线程池的 ,直接子线程中操作完再等到ui线程 anko库的
// doAsync {
// Log.e("TAG", " doAsync... [当前线程为:${Thread.currentThread().name}]")
// uiThread {
// Log.e("TAG", " uiThread.... [当前线程为:${Thread.currentThread().name}]")
// }
// }