跟着官网学习协程随笔

我在android开发中断断续续也使用到了协程,之前都是基于能用,但没有深究,导致每次使用都是机械调用。这次得空 看着官网学习学习,简单记录一下。 附上官网地址:https://developer.android.google.cn/kotlin/coroutines?hl=zh-cn#features

协程是一种并发设计模式,您可以在 Android 平台上使用它来简化异步执行的代码。

简单来说就是可以用它来执行异步的一些操作,优雅的写代码。

场景:界面上有一个按钮,点击之后调用请求网络,通过ViewModel的方法执行,获取到数据之后在更新到界面的一个文本。这个开发中最普遍的 一个使用场景。

原来的操作中会在点击之后调用三方的网络请求执行在IO线程中,最后请求到了数据后,通过LiveData 等 再更新到UI界面

现在的操作是 在viewModel中

复制代码
class TestViewModel : ViewModel() {
    fun requestHttp(){
        //开启协程
        viewModelScope.launch {
           val value = doSomeing()
           //更新UI
        }
    }

private suspend fun doSomeing():String {
    //模拟耗时
    delay(6000)
    retutn "结果"
}
}

自己不用单独开线程执行,直接调用协程处理,至于更新UI,可以使用

StateFlow 或者 SharedFlow

复制代码
StateFlow   状态持有者   始终有值
SharedFlow  事件发射器   每次发送新的

两种都可以用来更新UI使用,看场景区分 StateFlow总是会有一个值,随时可以获取,SharedFlow有点像到点执行,错过就没有了。

复制代码
1:StateFlow  
private val _uiState = MutableStateFlow(LatestNewsUiState.Success(emptyList()))
val uiState: StateFlow<LatestNewsUiState> = _uiState
复制代码
_uiState.value = LatestNewsUiState.Success(favoriteNews)  //viewModel发送
复制代码
repeatOnLifecycle(Lifecycle.State.STARTED) { //界面中接收
    latestNewsViewModel.uiState.collect { uiState ->
        // New value received
        when (uiState) {
            is LatestNewsUiState.Success -> showFavoriteNews(uiState.news)
            is LatestNewsUiState.Error -> showError(uiState.exception)
        }
    }
}

2:SharedFlow

复制代码
private val _tickFlow = MutableSharedFlow<Unit>(replay = 0)
val tickFlow: SharedFlow<Unit> = _tickFlow
复制代码
_tickFlow.emit(Unit) //viewModel 发送
复制代码
tickHandler.tickFlow.collect { //界面接收
                refreshLatestNews()
            }

Dispatchers的浅见

通过协程调用方法中

复制代码
viewModelScope.launch {
    // 默认在 Dispatchers.Main 上启动
    val result = getUsers()  // 挂起函数,自动切换IO
    updateUI(result)        // 直接在主线程更新UI
}

直接在方法体中顺序执行下来,很优雅

复制代码
viewModelScope.launch(Dispatchers.IO) {
    // 在IO线程池启动
    val result = getUsers()  // 挂起函数
    // 不能直接更新UI!
    withContext(Dispatchers.Main) {
        updateUI(result)    // 需要切回主线程
    }
}

也可以自己切换IO,但是最终需要切换Main 更新UI

launch 和 async 区别

复制代码
// 基本用法 launch 
viewModelScope.launch {
    // 执行一些操作
   analytics.log(event) // 不关心结果
}
复制代码
// 基本用法 async 
viewModelScope.launch {
    // 启动异步任务
    val deferred: Deferred<String> = async {
        fetchData()  // 返回 String
    }

    // 等待执行结果
    val result: String = deferred.await()
}

自定定义作用域

复制代码
class ExampleClass {
        //自己也可以创建作用域,但是要记得及时清理
    val scope = CoroutineScope(Job() + Dispatchers.Main)
    fun exampleMethod() {
        scope.launch {
            fetchDocs()
        }
    }

    fun cleanUp() {
        scope.cancel()
    }
}
相关推荐
三品吉他手会点灯5 小时前
C语言学习笔记 - 20.C编程预备计算机专业知识 - 变量为什么必须的初始化【重点】
c语言·笔记·学习
sakiko_5 小时前
UIKit学习笔记1-创建项目(使用UIKit)、使用组件
笔记·学习
生信碱移6 小时前
PACells:这个方法可以鉴定疾病/预后相关的重要细胞亚群,作者提供的代码流程可以学习起来了,甚至兼容转录组与 ATAC 两种数据类型!
人工智能·学习·算法·机器学习·数据挖掘·数据分析·r语言
星幻元宇VR8 小时前
VR航空航天科普设备【VR时空直升机】
科技·学习·安全·生活·vr
_李小白8 小时前
【android opencv学习笔记】Day 2: Mat类(图片数据结构体)
android·opencv·学习
harder3219 小时前
RMP模式的创新突破
开发语言·学习·ios·swift·策略模式
jinanwuhuaguo9 小时前
OpenClaw工程解剖——RAG、向量织构与“记忆宫殿”的索引拓扑学(第十三篇)
android·开发语言·人工智能·kotlin·拓扑学·openclaw
程序猿乐锅10 小时前
【Tilas|第三篇】多表SQL语句
数据库·经验分享·笔记·学习·mysql
徐某人..10 小时前
基于i.MX6ULL平台的智能网关系统开发
arm开发·c++·单片机·qt·物联网·学习·arm
AOwhisky10 小时前
Kubernetes 学习笔记:集群管理、命名空间与 Pod 基础
linux·运维·笔记·学习·云原生·kubernetes