欧美一区二区三区老妇人-欧美做爰猛烈大尺度电-99久久夜色精品国产亚洲a-亚洲福利视频一区二区

怎么在Kotlin中利用Coroutines執(zhí)行異步加載

怎么在Kotlin中利用Coroutines執(zhí)行異步加載?針對(duì)這個(gè)問題,這篇文章詳細(xì)介紹了相對(duì)應(yīng)的分析和解答,希望可以幫助更多想解決這個(gè)問題的小伙伴找到更簡單易行的方法。

十年的赫山網(wǎng)站建設(shè)經(jīng)驗(yàn),針對(duì)設(shè)計(jì)、前端、開發(fā)、售后、文案、推廣等六對(duì)一服務(wù),響應(yīng)快,48小時(shí)及時(shí)工作處理。營銷型網(wǎng)站建設(shè)的優(yōu)勢(shì)是能夠根據(jù)用戶設(shè)備顯示端的尺寸不同,自動(dòng)調(diào)整赫山建站的顯示方式,使網(wǎng)站能夠適用不同顯示終端,在瀏覽器中調(diào)整網(wǎng)站的寬度,無論在任何一種瀏覽器上瀏覽網(wǎng)站,都能展現(xiàn)優(yōu)雅布局與設(shè)計(jì),從而大程度地提升瀏覽體驗(yàn)。創(chuàng)新互聯(lián)從事“赫山網(wǎng)站設(shè)計(jì)”,“赫山網(wǎng)站推廣”以來,每個(gè)客戶項(xiàng)目都認(rèn)真落實(shí)執(zhí)行。

引入Coroutines

//在application的build.gradle文件中的android節(jié)點(diǎn)添加如下的代碼
kotlin {
 experimental {
  coroutines 'enable'
 }
}

//添加下面兩行到依賴中
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:0.20"
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:0.20"

第一個(gè)Coroutines示例

通常我們加載一張圖片到ImageView中,異步的加載任務(wù)如下所示:

fun loadBitmapFromMediaStore(imageId: Int, 
        imagesBaseUri: Uri): Bitmap {
 val uri = Uri.withAppendedPath(imagesBaseUri, imageId.toString())
 return MediaStore.Images.Media.getBitmap(contentResolver, uri)
}

這個(gè)方法必須在后臺(tái)線程中執(zhí)行,因?yàn)樗麑儆谝粋€(gè)IO操作,這意味著我們有很多解決方案可以啟動(dòng)后臺(tái)任務(wù),一旦該方法返回一個(gè)bitmap,我們需要立即顯示在Imageview中。

imageView.setImageBitmap(bitmap)

這行代碼必須在主線程執(zhí)行,否則會(huì)crash。

以上三行代碼如果寫到一起將會(huì)導(dǎo)致程序卡死或者是閃退,這都取決于合理的選擇線程。接下來我們看一下使用kotlin的Coroutines是如何解決這個(gè)問題的:

val job = launch(Background) {
 val uri = Uri.withAppendedPath(imagesBaseUri, imageId.toString())
 val bitmap = MediaStore.Images.Media.getBitmap(contentResolver, 
 launch(UI) {
 imageView.setImageBitmap(bitmap)
 }
}

這里最重要的是launch()和參數(shù)Background和UI,launch()表示創(chuàng)建和啟動(dòng)一個(gè)Coroutine,Background參數(shù)CoroutineContext用來保證在后臺(tái)線程執(zhí)行,從而保證應(yīng)用程序不會(huì)卡死或者閃退,你可以聲明一個(gè)如下面所示的CoroutineContext。

internal val Background = newFixedThreadPoolContext(2, "bg")

這將創(chuàng)建一個(gè)新的上下文,并在執(zhí)行他的任務(wù)的時(shí)候使用兩個(gè)常規(guī)的線程。

接下來說launch(UI),這將觸發(fā)另一個(gè)coroutine,將執(zhí)行在Android
的主線程。

可取消

接下來的挑戰(zhàn)是處理跟Activity聲明周期相關(guān)的東西,當(dāng)你在加載一個(gè)任務(wù),還沒有執(zhí)行完的時(shí)候離開了該Activity,以至于他在調(diào)用imageView.setImageBitmap(bitmap)就會(huì)引起crash,所以我們?cè)陔x開該activity之前就需要取消該任務(wù),這里就用到了launch()方法的返回值job,當(dāng)activity調(diào)用onStop方法時(shí),我們需要使用job來取消任務(wù)

job.cancel()

這就像你使用Rxjava時(shí)調(diào)用dispose和使用AsyncTask時(shí)調(diào)用cancel函數(shù)是一個(gè)道理。

LifecycleObserver

Android Architecture Components 給安卓開發(fā)者提供了特別多強(qiáng)大的庫,其中之一就是Lifecycle API.給我們提供了一個(gè)簡便的方法用來實(shí)時(shí)的監(jiān)聽activity和fragment的生命周期,我們定義一下代碼與coroutines一起使用。

class CoroutineLifecycleListener(val deferred: Deferred<*>) : LifecycleObserver {
 @OnLifecycleEvent(Lifecycle.Event.ON_DESTROY)
 fun cancelCoroutine() {
 if (!deferred.isCancelled) {
  deferred.cancel()
 }
 }
}

我們創(chuàng)建一個(gè)LifecycleOwner的擴(kuò)展函數(shù):

fun <T> LifecycleOwner.load(loader: () -> T): Deferred<T> {
 val deferred = async(context = Background, 
      start = CoroutineStart.LAZY) {
 loader()
 }
 lifecycle.addObserver(CoroutineLifecycleListener(deferred))
 return deferred
}

這個(gè)方法中有太多新的東西,接下來一一解釋:

現(xiàn)在我們可以在一個(gè)activity或fragment中調(diào)用load() ,并從該函數(shù)中訪問生命周期成員,并將我們的CoroutineLifecycleListener添加為觀察者。

load方法需要一個(gè)loader作為參數(shù),返回一個(gè)通用類型T,在load方法中我,我們調(diào)用了另外一個(gè)Coroutine的創(chuàng)造者async()函數(shù),將會(huì)使用Background coroutine上下文在后臺(tái)線程中執(zhí)行任務(wù),注意這個(gè)方法還有另外一個(gè)參數(shù)start = CoroutineStart.LAZY,這意味著coroutine不會(huì)立即執(zhí)行,知道被調(diào)用為止。

coroutine接著會(huì)返回一個(gè)Defered<T>對(duì)象給調(diào)用者,這與我們之前的Job類似,但它也可以攜帶一個(gè)延遲值,如常規(guī)Java API中的JavaScript Promise或Future <T> ,更好的是他有一個(gè)await方法.

接下來我們定義另外一個(gè)擴(kuò)展函數(shù)then() ,這次是在Deferen<T>上面定義,是我們上面的load方法返回的類型,它還將一個(gè)lambda作為參數(shù),命名為block,它將T類型的單個(gè)對(duì)象作為其參數(shù)。

infix fun <T> Deferred<T>.then(block: (T) -> Unit): Job {
 return launch(context = UI) {
 block(this@then.await())
 }
}

這個(gè)函數(shù)將使用launch()函數(shù)創(chuàng)建另一個(gè)Coroutine ,這次在主線程上運(yùn)行。傳遞給此Coroutine的lambda(命名塊)將完成的Deferred對(duì)象的值作為其參數(shù)。我們調(diào)用await()來掛起這個(gè)Coroutine的執(zhí)行,直到Deferred對(duì)象返回一個(gè)值。

這里是coroutine變得如此令人印象深刻的地方。 await()的調(diào)用是在主線程上完成的,但是不會(huì)阻塞該線程的進(jìn)一步執(zhí)行。它將簡單地暫停該函數(shù)的執(zhí)行,直到它準(zhǔn)備好,當(dāng)它恢復(fù)并將延遲值傳遞給lambda時(shí)。coroutine暫停時(shí),主線程可以繼續(xù)執(zhí)行其他的事情。await函數(shù)是coroutine中的一個(gè)核心概念,是什么創(chuàng)造了整個(gè)事物如此有魔力。

load()函數(shù)中添加的生命周期觀察者將在我們的activity上調(diào)用onDestroy()后取消第一個(gè)coroutine。這也會(huì)導(dǎo)致第二個(gè)coroutine被取消,阻止block()被調(diào)用。

Kotlin Coroutine DSL

現(xiàn)在我們得到了兩個(gè)擴(kuò)展函數(shù)和一個(gè)會(huì)處理coroutine被取消的類,讓我們來看看如何使用:

load {
 loadBitmapFromMediaStore(imageId, imagesBaseUri)
} then {
 imageView.setImageBitmap(it)
}

上面的代碼中,我們將lambda方法傳給load函數(shù),該函數(shù)調(diào)用loadBitmapFromMediaStore方法,該函數(shù)必須在后臺(tái)線程上執(zhí)行,直到該方法返回一個(gè)Bitmap,load方法的返回值是Deferred<Bitmap> 。

作為擴(kuò)展函數(shù),then()方法使用infix聲明,盡管load方法中返回的是Deferred<Bitmap> ,但是將會(huì)傳送給then方法一個(gè)bitmap返回值,所以我們可以直接在then方法中調(diào)用imageView.setImageBitmap(it)

上面的代碼可以用于任何需要在后臺(tái)線程上發(fā)生的異步調(diào)用,以及返回值應(yīng)該返回到主線程的地方,就像上面的例子。它不像RxJava那樣可以編寫多個(gè)調(diào)用,但它更容易閱讀,可能會(huì)涵蓋很多最常見的情況。現(xiàn)在你可以安全地做這樣的事情,而不必?fù)?dān)心在每個(gè)調(diào)用中造成context泄漏或處理線程;

load { restApi.fetchData(query) } then { adapter.display(it) }

關(guān)于怎么在Kotlin中利用Coroutines執(zhí)行異步加載問題的解答就分享到這里了,希望以上內(nèi)容可以對(duì)大家有一定的幫助,如果你還有很多疑惑沒有解開,可以關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道了解更多相關(guān)知識(shí)。

網(wǎng)站欄目:怎么在Kotlin中利用Coroutines執(zhí)行異步加載
地址分享:http://chinadenli.net/article34/jsijse.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供虛擬主機(jī)、云服務(wù)器、網(wǎng)站制作自適應(yīng)網(wǎng)站、建站公司、關(guān)鍵詞優(yōu)化

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)

網(wǎng)站建設(shè)網(wǎng)站維護(hù)公司
乱女午夜精品一区二区三区| 国产色第一区不卡高清| 黑丝袜美女老师的小逼逼| 久久精品久久久精品久久| 一级欧美一级欧美在线播| 中文字幕亚洲精品乱码加勒比| 麻豆国产精品一区二区三区| 中文字幕中文字幕一区二区| 99久久国产精品亚洲| 国产永久免费高清在线精品| 午夜精品在线观看视频午夜| 欧美日韩一区二区综合| 亚洲视频在线观看免费中文字幕| 国产又色又爽又黄又大| 在线免费看国产精品黄片| 亚洲熟女诱惑一区二区| 国产精品日韩欧美第一页| 国产成人高清精品尤物| 国产精品福利一二三区| 空之色水之色在线播放| 日本欧美一区二区三区就| 真实国产乱子伦对白视频不卡 | 69久久精品亚洲一区二区| 亚洲国产婷婷六月丁香| 欧美精品女同一区二区| 成人区人妻精品一区二区三区| 大香伊蕉欧美一区二区三区| 欧美成人免费夜夜黄啪啪| 亚洲精品福利视频你懂的| 久久国产青偷人人妻潘金莲| 国产爆操白丝美女在线观看| 国产一二三区不卡视频| 精品欧美一区二区三久久| 欧美av人人妻av人人爽蜜桃| 欧美日韩免费观看视频| 色婷婷亚洲精品综合网| 国产成人午夜在线视频| 久久中文字幕中文字幕中文| 观看日韩精品在线视频| 超碰在线播放国产精品| 五月婷婷亚洲综合一区|