美文网首页
Kotlin 协程学习

Kotlin 协程学习

作者: 因为我的心 | 来源:发表于2021-07-18 23:14 被阅读0次

    一、前言:

    线程:操作系统调度的
    依附进程,在进程眼里,线程是是轻量级的
    创建一万个 线程 奔溃(内存溢出)

    协程:用户来控制
    在线程的眼里,协程是更轻量级的
    创建一万个 协程 没有任何问题

    协程与线程的区别:

    • 1、协程是通过编译技术实现 (不需要虚拟机 VM/操作系统 OS 的支持),通过插入相关代码来生效。与之相反,线程/进程是需要虚拟机 VM/操作系统 OS 的支持,通过调度 CPU 执行生效。
    • 2、线程阻塞的代价昂贵,尤其在高负载时的可用线程很少,阻塞线程会导致一些重要任务缺少可用线程而被延迟。协程挂起几乎无代价,无需上下文切换或涉及 OS。

    协程优秀博客:https://www.jianshu.com/u/a324daa6fa19

    二、使用:

    1、依赖:

     // 协程 支持包   ------   AndroidX 扩展包
    //引入协程包,里面包了core核心包
    implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.4.3'
    //不需要核心 包
    //implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:1.4.3"
    //java版本的(我们一般不用)
    // implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-java:1.3.2'
    

    2、阻塞式协程:

     fun click1(view: View) = runBlocking { // 外协程
            // 协程环境了  默认是:main线程
            launch(Dispatchers.IO) { // 内协程
                Log.e("click1: ", "launch ${Thread.currentThread().name}")
    
                repeat(10) {
                    Thread.sleep(1000)
                    Log.e("click1: ", "计数中: ${it}")
                }
            }
        }
    
    
     fun click2(view: View) = runBlocking {
            // 不适用协程
            // displayMethod(textView)
    
            // 使用协程
            displayMethodOk(textView)
        }
    
    
    fun click3(view: View) = runBlocking {
            // TODO 完成这种  异步线程  和  主线程  的切换,  这个需求:之前我们用RxJava实现过了哦
            // 1.注册耗时操作
            // 2.注册耗时操作完成后,更新注册UI
            // 3.登录耗时操作
            // 4.登录耗时操作完成后,更新登录UI
    
            // main
            launch {
    
                val pro = ProgressDialog(this@MainActivity)
                pro.setMessage("正在执行中...")
                pro.show()
    
                withContext(Dispatchers.IO) {
                    // 1.注册耗时操作  异步
                    Log.d("click3", "1.注册耗时操作: ${Thread.currentThread().name}")
                    Thread.sleep(2000)
                }
    
                // 2.注册耗时操作完成后,更新注册UI  main
                Log.d("click3", "2.注册耗时操作完成后,更新注册UI: ${Thread.currentThread().name}")
    
                withContext(Dispatchers.IO) {
                    // 3.登录耗时操作  异步
                    Log.d("click3", "3.登录耗时操作: ${Thread.currentThread().name}")
                    Thread.sleep(3000)
                }
    
                // 4.登录耗时操作完成后,更新登录UI
                Log.d("click3", "4.登录耗时操作完成后,更新登录UI: ${Thread.currentThread().name}")
    
                // pro.dismiss()
            }
    
        }
    
    displayMethodOk()调用
    // =====================
    fun displayMethodOk(textView: TextView) = runBlocking {
        /*launch {
            // main
    
            // 默认还是 main
            // Dispatchers.IO  异步
            val def = async(Dispatchers.IO) {
    
                // 异步线程
    
                true
                "String"
    
                // 不考虑异常的情况
                mOkHttpClient.newCall(mRequest).execute().body()?.string()
            }
    
            // main
            // 可以拿到异步执行后的结果
            textView.text = def.await()
        }*/
    
        // 下面是简化
        launch {
            textView.text = async(Dispatchers.IO) {
                mOkHttpClient.newCall(mRequest).execute().body()?.string()  // 异步的
            }.await()
        }
    }
    

    3、非阻塞式协程:

      // 非阻塞
        fun click4(view: View)  {
            // TODO 完成这种  异步线程  和  主线程  的切换,  这个需求:之前我们用RxJava实现过了哦
            // 1.注册耗时操作
            // 2.注册耗时操作完成后,更新注册UI
            // 3.登录耗时操作
            // 4.登录耗时操作完成后,更新登录UI
    
            // main
            GlobalScope.launch (Dispatchers.Main) {
    
                val pro = ProgressDialog(this@MainActivity)
                pro.setMessage("正在执行中...")
                pro.show()
    
                withContext(Dispatchers.IO) {
                    // 1.注册耗时操作  异步
                    Log.d("click3", "1.注册耗时操作: ${Thread.currentThread().name}")
                    Thread.sleep(2000)
                }
    
                // 2.注册耗时操作完成后,更新注册UI  main
                Log.d("click3", "2.注册耗时操作完成后,更新注册UI: ${Thread.currentThread().name}")
                textView.text = "注册成功,你可以去登录了"
                pro.setMessage(textView.text.toString())
    
                withContext(Dispatchers.IO) {
                    // 3.登录耗时操作  异步
                    Log.d("click3", "3.登录耗时操作: ${Thread.currentThread().name}")
                    Thread.sleep(3000)
                }
    
                // 4.登录耗时操作完成后,更新登录UI
                Log.d("click3", "4.登录耗时操作完成后,更新登录UI: ${Thread.currentThread().name}")
                textView.text = "登录成功,欢迎回来"
                pro.setMessage(textView.text.toString())
    
                pro.dismiss()
            }
    
        }
    

    4、非阻塞式协程取消:

    // 挂起 函数 标记
    suspend fun main() {
        val job = GlobalScope.launch {
            repeat(1000) {
                delay(10)
                println("111111111 $it")
            }
        }
    
        println("A")
    
        // 我只等你 100毫秒,时间到,我就结束你
        Thread.sleep(100)
        // job.cancel() // 一点点的时间差,不是非常
    
        job.cancelAndJoin() // 一点点的时间差,都不允许
    
    }
    

    相关文章

      网友评论

          本文标题:Kotlin 协程学习

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