您好,登錄后才能下訂單哦!
定義
Coroutine翻譯為協程,Google翻譯為協同程序,一般也稱為輕量級線程,但需要注意的是線程是操作系統里的定義概念,而協程是程序語言實現的一套異步處理的方法。
在Kotlin文檔中,Coroutine定義為一個可被掛起的計算實例,下面話不多說了,來一起看看詳細的介紹吧。
配置
build.gradle中dependencies 添加下面2行,注意coroutine目前仍處于experiment階段,但Kotline官方保證向前兼容。
dependencies { implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:0.22.5' implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:0.19.3" }
實例
我們看一個簡單Android示例:
activity_coroutine.xml
<?xml version="1.0" encoding="utf-8"?> <android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".coroutine.CoroutineActivity"> <TextView android:id="@+id/tvHello" android:layout_width="wrap_content" android:layout_height="wrap_content" /> </android.support.constraint.ConstraintLayout>
CoroutineActivity.kt
class CoroutineActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_coroutine) setup() } fun setup() { launch(UI) { // launch coroutine in UI context for (i in 10 downTo 1) { // countdown from 10 to 1 tvHello.text = "Countdown $i ..." // update text delay(1000) // wait half a second } tvHello.text = "Done!" } } }
運行程序 tvHello從10倒計時顯示到1,最后顯示"Done!"
代碼分析:
我們重點分析setup()函數
看到這里你可能會疑惑,Android開發中不是禁止在主線程下做延遲或者阻塞操作嗎?
我們回顧下Coroutine的定義:一個可被掛起的計算實例。
Coroutine不是線程,所以掛起Coroutine不會影響當前線程的運行。
取消Coroutine運行
我們修改下上面的代碼:
class CoroutineActivity : AppCompatActivity() { lateinit var job:Job override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_coroutine) setup() } fun setup() { job = launch(CommonPool) { // launch coroutine in UI context for (i in 10 downTo 1) { // countdown from 10 to 1 tvHello.text = "Countdown $i ..." // update text delay(1000) // wait half a second } tvHello.text = "Done!" } } override fun onPause() { super.onPause() job.cancel() } }
重點是 launch(UI)返回給一個job實例,通過job.cancel()取消coroutine。
Coroutine和thread關系
我們再分析下
launch(UI)
這行代碼是指將coroutine指派在UI線程上運行
當我們運行一段cpu耗時操作時,則需要將coroutine指定在非UI線程上。
我們寫成:
launch(){...}
這行代碼等價于:
launch(CommonPool){...}
我們分析下CommonPool的實現,發現它會根據當前cpu的核數創建一個線程池提供給Coroutine使用。
private fun createPlainPool(): ExecutorService { val threadId = AtomicInteger() return Executors.newFixedThreadPool(defaultParallelism()) { Thread(it, "CommonPool-worker-${threadId.incrementAndGet()}").apply { isDaemon = true } } } private fun defaultParallelism() = (Runtime.getRuntime().availableProcessors() - 1).coerceAtLeast(1)
總結:
通過上面的分析,我們理解了Coroutine是一個運行在線程上的可被掛起的計算單元實例,對Coroutine的delay,cancel操作不會影響線程的運行,線程的狀態變化對我們是透明的,我們不需要關心。
所以使用Coroutine,可以使我們更加方便得處理異步操作,比如網絡請求,數據存儲等。
好了,以上就是這篇文章的全部內容了,希望本文的內容對大家的學習或者工作具有一定的參考學習價值,如果有疑問大家可以留言交流,謝謝大家對億速云的支持。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。