欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Android協(xié)程代替Handler使用示例詳解

 更新時(shí)間:2024年01月31日 09:37:22   作者:xiangzhihong  
這篇文章主要為大家介紹了Android?協(xié)程代替Handler使用示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪

引言

在 Android 開(kāi)發(fā)中,我們經(jīng)常需要處理異步任務(wù),例如網(wǎng)絡(luò)請(qǐng)求、數(shù)據(jù)庫(kù)訪問(wèn)、耗時(shí)計(jì)算等等。為了在處理異步任務(wù)時(shí)能夠方便地更新 UI,Android 提供了 Handler 類(lèi)。然而,在使用 Handler 時(shí),我們需要處理一些繁瑣的問(wèn)題,例如線程間通信和內(nèi)存泄漏。為了簡(jiǎn)化這些問(wèn)題,Google 在 Android 3.0 引入了 AsyncTask 類(lèi),但它仍然有一些限制。最近,Kotlin 官方推出了 Kotlin 協(xié)程,它是一種輕量級(jí)的線程框架,可以在 Android 開(kāi)發(fā)中替代 Handler 和 AsyncTask,并提供更加簡(jiǎn)潔和強(qiáng)大的異步編程體驗(yàn)。

什么是協(xié)程

協(xié)程是一種輕量級(jí)的線程框架,它允許開(kāi)發(fā)者以順序的方式編寫(xiě)異步代碼,而無(wú)需關(guān)心線程的管理和同步問(wèn)題。協(xié)程的概念最早出現(xiàn)在 Erlang 語(yǔ)言中,后來(lái)被其他編程語(yǔ)言引入。Kotlin 協(xié)程是基于 JVM 的一種協(xié)程實(shí)現(xiàn),它允許開(kāi)發(fā)者以同步的方式編寫(xiě)異步代碼,并且可以與現(xiàn)有的異步框架(例如 Retrofit、Room 等)很好地集成。

使用協(xié)程的好處主要有以下幾點(diǎn):

  • 簡(jiǎn)化異步代碼:協(xié)程允許我們以順序的方式編寫(xiě)異步代碼,而不是嵌套的回調(diào)函數(shù)或者復(fù)雜的線程管理代碼。
  • 避免回調(diào)地獄:使用協(xié)程,我們可以將異步任務(wù)的邏輯寫(xiě)在一個(gè)連續(xù)的代碼塊中,而不是多個(gè)回調(diào)函數(shù)中,提高代碼的可讀性和可維護(hù)性。
  • 更好的錯(cuò)誤處理:協(xié)程提供了異常處理機(jī)制,可以很方便地捕獲和處理異步任務(wù)中的異常。
  • 更好的性能:協(xié)程使用非阻塞的方式執(zhí)行異步任務(wù),可以更好地利用系統(tǒng)資源,提高應(yīng)用的性能。
  • 更好的 UI 交互:協(xié)程允許我們?cè)谥骶€程中執(zhí)行異步任務(wù),從而方便地更新 UI。

使用協(xié)程代替 Handler

在 Android 中,我們經(jīng)常需要在子線程中執(zhí)行一些耗時(shí)的任務(wù),然后在主線程中更新 UI。使用 Handler,我們可以很方便地實(shí)現(xiàn)這個(gè)功能。然而,使用 Handler 時(shí),我們需要處理一些繁瑣的問(wèn)題,例如線程間通信和內(nèi)存泄漏?,F(xiàn)在,我們可以使用協(xié)程來(lái)簡(jiǎn)化這些問(wèn)題。

首先,我們需要添加協(xié)程庫(kù)的依賴。在項(xiàng)目的 build.gradle 文件中,加入以下代碼:

dependencies {
    implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.6.1'
}

接下來(lái),我們可以在任何一個(gè)函數(shù)中創(chuàng)建一個(gè)協(xié)程。在 Kotlin 中,我們使用 suspend 修飾符來(lái)聲明一個(gè)掛起函數(shù),它可以在協(xié)程中被調(diào)用。在協(xié)程中,我們可以使用 launch 函數(shù)來(lái)啟動(dòng)一個(gè)新的協(xié)程,并在其中執(zhí)行一些異步任務(wù)。

下面是官方一個(gè)使用協(xié)程替代 Handler 的示例代碼:

fun main(args: Array<String>) {
    launch(CommonPool) {
        delay(1000L) 
        println("World!") 
    }
    println("Hello,")
    Thread.sleep(2000L)
}
/* 
運(yùn)行結(jié)果: ("Hello,"會(huì)立即被打印, 1000毫秒之后, "World!"會(huì)被打印)
Hello, 
World!
*/

此處解釋一下delay方法:

在協(xié)程里delay方法作用等同于線程里的sleep, 都是休息一段時(shí)間, 但不同的是delay不會(huì)阻塞當(dāng)前線程, 而像是設(shè)置了一個(gè)鬧鐘, 在鬧鐘未響之前, 運(yùn)行該協(xié)程的線程可以被安排做了別的事情, 當(dāng)鬧鐘響起時(shí), 協(xié)程就會(huì)恢復(fù)運(yùn)行.

在Android中使用協(xié)程

在Android中使用協(xié)程需要引入如下兩個(gè)庫(kù):

implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:1.6.1"
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:1.6.1"

官方建議有生命周期的類(lèi)繼承 CoroutineSocpe,這樣就能讓全部協(xié)程跟著生命周期結(jié)束。

MainActivity : AppCompatActivity(), CoroutineScope by MainScope(){
    override fun onDestroy(){
        super.onDestory()
        cancel()
     }
}

在村莊UI邏輯類(lèi)中使用:

class MainActivityFacede : CoroutineScope {
    private val job = Job()
    override val coroutineContext: CoroutineContext
        get() = Dispatchers.Main + job
    fun destroy() {
        job.cancel()
    }
}

運(yùn)行協(xié)程

Android有兩種運(yùn)行協(xié)程,分別是launch與async。下面我們來(lái)說(shuō)一下它們的一些區(qū)別:

  • aunch 沒(méi)有返回值,或者說(shuō)返回只是 job ,能夠知道任務(wù)的狀態(tài),卻不能攜帶返回結(jié)果。
  • async 有返回值,也就是返回的是 Deferred ,它是繼承的 job ,所有job有的,它都有,還具備了job沒(méi)有的攜帶數(shù)據(jù)回來(lái)的能力。
  • launch 可以用來(lái)運(yùn)行不需要操作結(jié)果的協(xié)程(如文件刪除,創(chuàng)建等)
  • async 可以用來(lái)運(yùn)行異步耗時(shí)任務(wù)并且需要返回值的任務(wù)(網(wǎng)絡(luò)請(qǐng)求,數(shù)據(jù)庫(kù)操作,文件讀寫(xiě)等)。

以下是Job和Deferred的生命周期說(shuō)明。

以下是一個(gè)使用示例:

private suspend fun getWebTime(): Long {
    var result = RequeastTest.getInstance().start()
    val name = Thread.currentThread().name
    if (!coroutines.contains(name)) {
        coroutines.add(name)
    }
    return result
}
launch() {
    //do sth
    var time = withContext(Dispather.IO){
        getWebTime()
    }
    //update UI
}
launch {
    var deferred = async(Dispather.IO) {
        //發(fā)起網(wǎng)絡(luò)請(qǐng)求..
        getWebTime()
    }
    //do sth ...
    var value = deferred.await()
    //do sth...
}

可以看到,我們使用了兩個(gè)新的東西Dispather和suspend。

Dispther可以理解為是一個(gè)協(xié)程調(diào)度器,用來(lái)調(diào)度協(xié)程跑到哪個(gè)線程中。Dispather 可以在 launch、async 等啟動(dòng)協(xié)程時(shí),指定在哪個(gè)線程里面運(yùn)行,也可以在協(xié)程中,使用 withContext(Dispather.) 來(lái)切換線程,使用 withContext 切換線程時(shí),有返回值。

Suspend是協(xié)程里面唯一一個(gè)修飾符,用來(lái)修改函數(shù)的,表明函數(shù)是一個(gè)掛起函數(shù),協(xié)程編譯器會(huì)在編譯期間進(jìn)行CPS變換,去做一些不可描述的事情。用suspend修飾的函數(shù),只能在協(xié)程體和同樣使用 suspend 修飾的函數(shù)中調(diào)用。

另外,我們還可以同時(shí)進(jìn)行多個(gè)網(wǎng)絡(luò)請(qǐng)求,并在全部請(qǐng)求完畢之后進(jìn)行數(shù)據(jù)整理,統(tǒng)一渲染界面,如下所示。

launch {
    var userInfoDeferred = async {
        //獲取用戶基本信息
        getUserInfo(aid)
    }
    var userTeamsDeferred = async{
        //獲取用戶團(tuán)隊(duì)..
        getUserTeams(aid)
    }
    var userOrgsDeferred =  async {
        //獲取用戶組織機(jī)構(gòu)
        getUserOrgs(aid)
    }
    var userInfo = userInfoDeferred.await()
    var userTeams = userTeamsDeferred.await()
    var userOrgsDeferred = userOrgsDeferred.await()
    //渲染UI 
}

事實(shí)上,對(duì)于協(xié)程的簡(jiǎn)單理解與使用,協(xié)程到底是什么, 很難給出具體的定義, 就算能給出具體定義, 也會(huì)非常抽象難以理解的。另一方面, 協(xié)程可以說(shuō)是編譯器的能力, 因?yàn)閰f(xié)程并不需要操作系統(tǒng)和硬件的支持(線程需要), 是編譯器為了讓開(kāi)發(fā)者寫(xiě)代碼更簡(jiǎn)單方便, 提供了一些關(guān)鍵字, 并在內(nèi)部自動(dòng)生成了一些支持型代碼。

總的來(lái)說(shuō),協(xié)程就是一種輕量級(jí)的線程框架,它允許開(kāi)發(fā)者以順序的方式編寫(xiě)異步代碼。并且,相比傳統(tǒng)的 Handler 和 AsyncTask編程,協(xié)程能夠更好的利用系統(tǒng)資源,提高代碼的可讀性和可維護(hù)性。

以上就是Android 協(xié)程代替Handler使用示例詳解的詳細(xì)內(nèi)容,更多關(guān)于Android 協(xié)程代替Handler的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

最新評(píng)論