跟着官网学习协程随笔

我在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()
    }
}
相关推荐
是小蟹呀^2 小时前
图像分类里的小样本学习(Few-shot Image Classification)
学习·分类·数据挖掘
●VON2 小时前
React Native for OpenHarmony:猜数字游戏完整技术实现文档
学习·react native·react.js·游戏·开源鸿蒙·von
民乐团扒谱机2 小时前
【微实验】Zhang-Suen 快速并行细化算法与MATLAB实现
人工智能·学习·算法·计算机视觉·数学建模·matlab
GHL2842710903 小时前
TeamTalk-msg_server学习
运维·服务器·c++·学习
试试勇气3 小时前
Linux学习笔记(十三)--动静态库
笔记·学习
好好学习天天向上~~3 小时前
3_Linux学习总结_基础指令
linux·服务器·学习
AI视觉网奇3 小时前
ue metahuman自动绑定实战
笔记·学习·ue5
tb_first3 小时前
万字超详细苍穹外卖学习笔记3
java·jvm·笔记·学习·spring·tomcat·maven
coldstarry3 小时前
sheng的学习笔记-AI-adaboost(Adaptive Boosting)
人工智能·笔记·学习