Coroutines
什么是协程?(摘自官网)
- Asynchronous or non-blocking programming is an important part of the development landscape. 用于异步或非阻塞 编程。
简单概括 :
同步的方式去编写异步执行的代码
- 协程依赖于线程
- 协程挂起时不需要阻塞线程,几乎是无代价的.
- 一个线程中可以创建N个协程
协程的创建/启动
- runBlocking 启动一个新的协程并阻塞调用它的线程
- launch:Job 启动一个协程但不会阻塞调用线程(CoroutineScope作用域内调用)
- async:Deferred<T> 启动一个协程但不会阻塞调用线程(CoroutineScope作用域内调用)
协程作用域(CoroutineScope)
-
GlobalScope 全局顶级协程 (现在 GlobalScope 类已被 @DelicateCoroutinesApi 注解所标记) 全局范围
启动一个协程:
image.png -
CoroutineScope https://developer.android.com/topic/libraries/architecture/coroutines
-
MainScope 主线程的作用域,全局范围
-
lifecycleScope 生命周期范围,用于activity等有生命周期的组件,DESTROYED结束。
class MyFragment: Fragment() {
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
viewLifecycleOwner.lifecycleScope.launch {
val params = TextViewCompat.getTextMetricsParams(textView)
val precomputedText = withContext(Dispatchers.Default) {
PrecomputedTextCompat.create(longTextContent, params)
}
TextViewCompat.setPrecomputedText(textView, precomputedText)
}
}
}
- viewModelScope:viewModel范围,ViewModel被回收时结束
class MyViewModel: ViewModel() {
init {
viewModelScope.launch {
// Coroutine that will be canceled when the ViewModel is cleared.
}
}
}
val user: LiveData<User> = liveData {
val data = database.loadUser() // loadUser is a suspend function.
emit(data)
}
异步、并发、并行
异步
- 是一种编程模型
- 独立于主程序流事件的发生
- 异步启动的操作,不会立即阻塞程序,并同时发生
异步是实现非阻塞和并发编程的编程模型
并发
- 独立执行任务的组合
- 所有任务的工作都可以以某种任意顺序交错
- 这些任务不一定必须同时执行
它的主要目标是结构,而不是并行性
并行
- 同时执行多个事物
- 与多个任务的执行有关
并发就是一次处理很多事情,并行就是一次做很多事情
协程中的并发和并行
- 挂起而非阻塞 ,一个并发的例子
import kotlinx.coroutines.*
import kotlin.system.measureTimeMillis
fun main(args: Array<String>) =
runBlocking {
val time = measureTimeMillis {
val one = async { doSomethingUsefulOne() }
val two = async { doSomethingUsefulTwo() }
println("The answer is ${one.await()} ${two.await()}")
}
println("Completed in $time ms")
}
suspend fun doSomethingUsefulTwo() :Int{
delay(1000L)
println("two")
return 2
}
suspend fun doSomethingUsefulOne():Int {
delay(1000L)
println("one")
return 1
}
one
two
The answer is 1 2
Completed in 1020 ms
并行
- GlobalScope
- 指定协同调度程序
- 暂停阻塞
suspend fun doSomethingUsefulOne(): BigInteger = withContext(Dispatchers.Default) {
measureTimedValue {
println("in doSomethingUsefulOne")
BigInteger(1500, Random()).nextProbablePrime()
}
}.also {
println("Prime calculation took ${it.duration} ms")
}.value
网友评论