美文网首页
Android 上的 Kotlin 协程(Coroutines)

Android 上的 Kotlin 协程(Coroutines)

作者: 行走中的3卡 | 来源:发表于2022-10-18 11:00 被阅读0次

    官网介绍:
    https://developer.android.com/kotlin/coroutines

    一、协程的概念

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

    在 Android 上,协程有助于管理长时间运行的任务.

    二、协程的特点

    协程是在 Android 上进行 异步编程 的推荐解决方案。值得关注的特点包括:
    (1)轻量:可以在单个线程上运行多个协程
    因为协程支持挂起,不会使正在运行协程的线程阻塞
    挂起比阻塞 节省内存 ,且支持多个 并行操作
    (2)内存泄漏更少:使用结构化并发机制 在 一个作用域 内执行 多项操作
    (3)内置取消支持:取消操作 会自动 在运行中的 整个协程层次结构 内传播。
    (4)Jetpack 集成:许多 Jetpack 库 都包含提供全面 协程支持扩展
    某些库还提供自己的协程作用域,可供用于结构化并发。

    三、示例

    1. 示例概览

    实现:发出网络请求 并 将结果返回到 主线程,然后应用可以在 主线程上 向用户 显示结果。

    具体而言,ViewModel 架构组件 会在 主线程 上调用 代码库层,以触发 网络请求
    会介绍多种使用 协程 确保 主线程畅通的解决方案:

    withContext()函数 转移线程 , 并 结合 suspend( 挂起)关键字 强制从协程里 调用.
    viewModelScope.launch 启动新协程

    ViewModel 包含一组可直接 与协程配合 使用的 KTX 扩展。这些扩展是 lifecycle-viewmodel-ktx 库.

    2. 依赖项信息

    应用的 build.gradle

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

    3. 具体类

    3.1 结果类

    sealed class Result<out R> {
        data class Success<out T>(val data: T) : Result<T>()
        data class Error(val exception: Exception) : Result<Nothing>()
    }
    

    3.2 存储库类,触发 网络请求.

    class LoginRepository(private val responseParser: LoginResponseParser) {
        private const val loginUrl = "https://example.com/login"
        suspend fun makeLoginRequest(
            jsonBody: String
        ): Result<LoginResponse> {
    
            // Move the execution of the coroutine to the I/O dispatcher
            return withContext(Dispatchers.IO) {
                // Blocking network request code
                val url = URL(loginUrl)
                (url.openConnection() as? HttpURLConnection)?.run {
                    requestMethod = "POST"
                    setRequestProperty("Content-Type", "application/json; utf-8")
                    setRequestProperty("Accept", "application/json")
                    doOutput = true
                    outputStream.write(jsonBody.toByteArray())
                    return Result.Success(responseParser.parse(inputStream))
                }
                return Result.Error(Exception("Cannot open HttpURLConnection"))
            }
        }
    }
    

    分析:
    (1) 使用 withContext()函数将 协程的执行操作 移至其他线程( I/O 线程)
    (2) suspend 关键字进行标记函数,强制从协程内调用它.

    3.3 登录ViewModel, 在主线程调用 存储库 类.

    class LoginViewModel(
        private val loginRepository: LoginRepository
    ): ViewModel() {
    
        fun login(username: String, token: String) {
    
            // Create a new coroutine on the UI thread
            viewModelScope.launch {
                val jsonBody = "{ username: \"$username\", token: \"$token\"}"
    
                // Make the network call and suspend execution until it finishes
                val result = loginRepository.makeLoginRequest(jsonBody)
    
                // Display result of the network request to the user
                when (result) {
                    is Result.Success<LoginResponse> -> // Happy path
                    else -> // Show error in UI
                }
            }
        }
    }
    

    分析:
    (1) 应用从主线程上的 View 层调用 login() 函数。
    (2) launch 在主线程上创建新协程,然后协程开始执行。
    (3) 在协程内,调用 loginRepository.makeLoginRequest()
    现在会挂起协程的进一步执行操作,
    直至 makeLoginRequest() 中的 withContext 块结束运行。
    (4) withContext 块结束运行后,
    login() 中的协程在主线程上恢复执行操作,
    并返回网络请求的结果。
    (5) 处理 Repository 层可能抛出的异常, 使用的是 try-catch 块

    4. 一些总结:

    (1) viewModelScope.launch 里面调用 使用suspend 声明 且 使用了withConext()(转移到其它调度程序的某个线程的)函数.

    (2) viewModelScope 与界面生命周期绑定(默认在主调度程序 Dispatchers.Main),
    因此,当用户离开屏幕时,此协程启动的操作将自动取消。

    (3) 当协程调用标记为 suspend 的函数时,
    它不会像常规函数调用一样在函数返回之前进行阻塞,而是挂起执行,
    直到结果就绪为止,然后从上次停止的位置恢复并使用返回的结果。
    当它挂起并等待结果时,它会取消阻塞正在运行它的线程,以便其他函数或协程可以运行。
    Kotlin编译器会把suspend 声明的函数,转换成callback形式的代码

    (4) 重要提示:suspend 关键字不指定运行代码的线程。挂起函数可以在后台线程或主线程上运行。

    (5) 一个协程里可以运行多个线程

    (6) suspend function 的伪代码介绍


    suspend function.JPG

    (6) Coroutine 的基本内容(Android 官方介绍)


    coroutine 内容.JPG

    -- End --

    相关文章

      网友评论

          本文标题:Android 上的 Kotlin 协程(Coroutines)

          本文链接:https://www.haomeiwen.com/subject/msvjzrtx.html