当前位置: 首页 > news >正文

Kotlin协程简介

文章目录

    • 官网地址
    • 1 来源
    • 2 出现原因
    • 3 特点
        • 1) 轻量
        • 2)内存泄漏更少
        • 3)内置取消支持
        • 4)Jetpack 集成
    • 4 依赖项信息
    • 5 在后台线程中执行
      • 6 使用协程确保主线程安全
      • 7 处理异常

官网地址

https://developer.android.google.cn/kotlin/coroutines?hl=zh-cn

1 来源

协程是一种并发设计模式,您可以在 Android 平台上使用它来简化异步执行的代码。协程是在版本 1.3 中添加到 Kotlin 的,它基于来自其他语言的既定概念。

2 出现原因

在 Android 上,协程有助于管理长时间运行的任务,如果管理不当,这些任务可能会阻塞主线程并导致应用无响应。使用协程的专业开发者中有超过 50% 的人反映使用协程提高了工作效率。

3 特点

1) 轻量
 您可以在单个线程上运行多个协程,因为协程支持挂起,不会使正在运行协程的线程阻塞。挂起比阻塞节省内存,且支持多个并行操作
2)内存泄漏更少
使用结构化并发机制在一个作用域内执行多项操作
3)内置取消支持
取消功能会自动通过正在运行的协程层次结构传播
4)Jetpack 集成
许多 Jetpack 库都包含提供全面协程支持的扩展。某些库还提供自己的协程作用域,可供您用于结构化并发

4 依赖项信息

dependencies { 
	implementation("org.jetbrains.kotlinx:kotlinx-coroutines-android:1.3.9")
}

5 在后台线程中执行

网络请求发出时阻塞界面线程。如需将执行操作移出主线程,最简单的方法是创建一个新的协程,然后在 I/O 线程上执行网络请求
class LoginViewModel(
    private val loginRepository: LoginRepository
): ViewModel() {

    fun login(username: String, token: String) {
        // Create a new coroutine to move the execution off the UI thread
        viewModelScope.launch(Dispatchers.IO) {
            val jsonBody = "{ username: \"$username\", token: \"$token\"}"
            loginRepository.makeLoginRequest(jsonBody)
        }
    }
}

6 使用协程确保主线程安全

使用协程库中的 withContext() 函数将协程的执行操作移至其他线程

由于 makeLoginRequest 将执行操作移出主线程,login 函数中的协程现在可以在主线程中执行

login 函数现在按以下方式执行

  • 应用从主线程上的 View 层调用 login() 函数
  • launch 在主线程上创建新协程,然后协程开始执行
  • 在协程内,调用 loginRepository.makeLoginRequest() 现在会挂起协程的进一步执行操作,直至 makeLoginRequest() 中的 withContext 块结束运行
  • withContext 块结束运行后,login() 中的协程在主线程上恢复执行操作,并返回网络请求的结果

7 处理异常

为了处理 Repository 层可能抛出的异常,请使用 Kotlin 对异常的内置支持。在以下示例中,我们使用的是 try-catch 块

class LoginViewModel(
    private val loginRepository: LoginRepository
): ViewModel() {

    fun makeLoginRequest(username: String, token: String) {
        viewModelScope.launch {
            val jsonBody = "{ username: \"$username\", token: \"$token\"}"
            val result = try {
                loginRepository.makeLoginRequest(jsonBody)
            } catch(e: Exception) {
                Result.Error(Exception("Network request failed"))
            }
            when (result) {
                is Result.Success<LoginResponse> -> // Happy path
                else -> // Show error in UI
            }
        }
    }
}

相关文章:

  • pandas nlargest()的详细用法
  • ubuntu 20.04 passwd 指令不能使用
  • 小程序搭建OA项目首页布局界面
  • Redis 主从复制,哨兵,集群——(3)集群篇
  • 【大数据开发技术】实验06-SequenceFile、元数据操作与MapReduce单词计数
  • logback.xml配置详解
  • 免费的国产数据集成平台推荐
  • 汽车智能制造中的RFID技术在供应链生产管理中的应用
  • C++项目实战——基于多设计模式下的同步异步日志系统-⑩-异步缓冲区类与异步工作器类设计
  • DTI综述(更新中)
  • Eclipse Xtext 实现PLC ST 语言到C的转换
  • 【LeetCode字符串】--14.最长公共前缀
  • 小红书达人怎么对接,博主沟通流程汇总!
  • 切水果游戏开发1
  • 关于电路的输入阻抗与输出阻抗的理解
  • 面试算法32:有效的变位词
  • 【论文阅读】基于卷积神经的端到端无监督变形图像配准
  • SQLAlchemy学习-12.查询之 order_by 按desc 降序排序
  • 竞赛选题 深度学习YOLO安检管制物品识别与检测 - python opencv
  • STM32内部flash闪存的总结
  • 马克思主义理论研究教学名师系列访谈|丁晓强:马克思主义学者要更关注社会现实的需要
  • 奈雪的茶叫停“能喝奶茶就不要喝水”宣传,当地市监称不要误导消费者
  • 李铁案二审驳回上诉,维持一审有期徒刑20年的判决
  • 马上评丨市长信箱“已读乱回”,群众在意的是什么
  • 国家发改委:建立实施育儿补贴制度
  • 商超展销延长、专区专柜亮相……上海“外贸拓内销”商品与市民见面