Kotlin 协程学习

2021-07-18  本文已影响0人  因为我的心

一、前言:

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

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

协程与线程的区别:

协程优秀博客: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() // 一点点的时间差,都不允许

}
上一篇 下一篇

猜你喜欢

热点阅读