跟着官网学习协程随笔

我在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 小时前
别再把 inline 当性能开关:Kotlin 内联、noinline、crossinline 与 reified 实战详解
kotlin
Kapaseker8 小时前
Kotlin Toolchain 0.11 发布:主要是把 Amper 干没了
android·kotlin
黄林晴8 小时前
AndroidX 官宣信号:Compose版WebView要来了!
kotlin
如此风景1 天前
Kotlin Flow操作符学习
android·kotlin
plainGeekDev1 天前
GreenDAO → Room
android·java·kotlin
plainGeekDev1 天前
ButterKnife → ViewBinding
android·java·kotlin
Kapaseker2 天前
一文吃透 Kotlin 集合操作符
android·kotlin
plainGeekDev3 天前
Activity 间传值 → Navigation 参数
android·java·kotlin
plainGeekDev3 天前
onActivityResult → ActivityResult API
android·java·kotlin
alexhilton4 天前
Android车载OS中的Remote Compose
android·kotlin·android jetpack