跟着官网学习协程随笔

我在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()
    }
}
相关推荐
辣知7 小时前
辣知·化智77 三千年接力写就的一本书
学习
一木 之林7 小时前
Dify学习笔记 01 · 平台入门与实战:部署、五类应用、RAG与MCP(第1-16集)
人工智能·笔记·学习·计算机视觉
摸鱼 特供版7 小时前
一款边录边标注的轻量截图录屏工具
windows·学习·电脑·音视频·软件需求
陈年老古董7 小时前
Hive 函数学习笔记(下):窗口函数与经典案例
hive·笔记·学习
罗西的思考8 小时前
[Agent Memory / 强化学习] MemPO源码学习笔记 — (6)— 奖励机制
人工智能·笔记·学习
拾饵9429 小时前
第六周第二个项目笔记:FinInsRAG 项目学习笔记(零基础版)以及简历书写
笔记·学习
Lost_the_wind9 小时前
MySQL 学习笔记三
笔记·学习·mysql
欣欣之王来了9 小时前
开发环境准备:Node.js、npm、VS Code安装配置
前端·学习·架构·项目·vue3教程
火眼金睛记单词10 小时前
阅读理解核心词汇:破解英语阅读难题的利器
经验分享·学习
老王爱玩车10 小时前
文件操作从打开到缓冲区
c语言·开发语言·学习