快,再快點,我們都討厭等待
但同時執行多項任務是非常需要技巧的,我們要在意順序、資源,更中意的是如果沒管理好,每次執行的順序可能會不一樣,造成不同的副作用並出現問題,異步併發非常方便,但也需要很多技巧
那我們所能做的是什麼呢? 不要異步 徹底了解異步工具,在
Kotlin, coroutine 是非常好的選項,簡而言之 coroutine 可以讓我們用同步方式寫出異步代碼
在前一篇文章中,我們已經提過了coroutine,而在這篇我會做個正式的簡單介紹,畢竟 coroutine 也是個大主題,可以去看我去年寫的 30 天 coroutine
在安卓裡,我們有很多方式實現異步 handler, thread, rx ...etc, 而最簡單的方式是 @runOnUiThread coroutine, 透過這個庫,我們能夠輕鬆的在不同線程切換任務
CoroutineScope(Job()).launch { //coroutinescope
launch { //child coroutnescope
//task
}
async {//child coroutinescope
//task
}
}
在上面的程式碼中,我們創建了一個 CoroutineScope 類別,並在其 launch 裡面執行任務,如你所見,我們可以呼叫 launch or async 在 launch or async 裡面,而這會幫我們創建一個子 coroutineScope 於父 coroutineScope 之下,而 launch 和async的差異是
launch 建立一個子域,不回傳值
async 建立一個子域,並回傳值,但需要呼叫 await
async 的回傳值會包在 Deferred
裡面
val asyncString = async{
"hello"
}
asyncString.apply { //Deferred<String>
await()//String
}
coroutine 的核心之一就是 suspend
, 他是一個函式修飾符,我們可以將它夾在函式前面
suspend fun get(){
withContext(Dispatchers.IO){
}
}
有了這個修飾符,我們就能一個超厲害的功能,看圖
沒錯,這個庫就會利用調配器,幫我們在不同線程之間調度任務,並在結束時返回原線程
現在我們知道了,我們要在 coroutinescope 裡面執行任務,而 suspend 的設計核心在切換線程,那調度氣勢要調度什麼呢
我們可以使用調度氣在不同線程裡面執行任務,但我們無法決定要哪一個實體,在底層實作,調度氣會為我們管理任務調度和線程管理,而我們總共有四種調度器
CoroutineScope 的生命週期取決於他的 Job()
,我們可以將其認作為每個 CoroutineScope 的 ID,而我們只能為根 coroutine 指定 Job,其他的 CoroutineScope 都會由套件指定
如果我們想要取消 coroutinescope,可以使用job.cancel()
, 這會丟出一個 cancelException
, 要執行這項操作後 CoruotineScope
實例才能被垃圾回收掉
再看看安卓的案例,我們總是在關心生命週期,官方也為此提供了工具 lifecycleScope
and. viewModelScope
, 我們可以用此特製 corotuinescope ,他們會在生命週期結束後自動取消
已上是基本的 coroutine 用法,想了解更多進階的請看這邊 link
Quicker, faster, we all hate waiting,
but doing many things at the same time is tricky, we have to care about order, resources, and the most important thing is that tasks might run in different order each time, cause different side effects, cause errors under the hood, control multiple tasks is very difficult.
the best we can do is don't doing anything understand a async task tool and use it well, in Kotlin, coroutine is the best opinion, in short speaking coroutine allows us to do task async, but write code in sync way
in the previous article, we have an example in coroutine, but in this article, I will introduce it officially, or you can check those articles I wrote last year
In Android, we have several ways to run async task, handler, thread, rx ...etc, the easiest way is coroutine, with this library, we can easily to switch task between task
a simple demo will look like this
CoroutineScope(Job()).launch { //coroutinescope
launch { //child coroutnescope
//task
}
async {//child coroutinescope
//task
}
}
we will create a CoroutineScope class, and and run task inside launch, as you can see, we can implement launch or async inside it as well, both launch and async will create a child coroutinescope under it parent coroutinescope, the different between them is
launch will create a child scope, and do not return value
async will create a child scope, and return the last value by calling await
async will wrap the return value inside Deferred
val asyncString = async{
"hello"
}
asyncString.apply { //Deferred<String>
await()//String
}
The core of coroutine is suspend
, it is a function modifier, we can add it before function
suspend fun get(){
withContext(Dispatchers.IO){
}
}
with this simple modifier, we now have a great feature, check this image
as you can see, the library using dispatcher switch task from main to io, and switch back
Now we know that, we need to run everything inside coroutinescope, and the design of suspend is to switch tasks between threads, then what is the dispatcher means?
we can use Dispatcher to switch task between thread, but we can't decide will specific one, under the hood, the Dispatcher will manage the task dispatch, there are four default Dispatcher we have
The life of CoroutineScope up to its Job()
, you can take it as an ID for each coroutinescope, each we can only specific job to a root coroutine, beside that, all the jobs will auto generate by os.
if we want to cancel a coroutinescope, we can use job.cancel()
, which will throw a cancelException
, by throwing this, the CoruotineScope
instance could be recycle by garbage collect by OS
Take android as an example, we have to care about the lifecycle, the android official created a useful tool, lifecycleScope
and. viewModelScope
, we can easy create corotuinescope will cancel with the lifecycle in fragment, activity ot viewModel
the basic usage of coroutine is simple, for more advanced technique, please check out the link