IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 移动开发 -> Android kotlin协程浅析笔记 -> 正文阅读

[移动开发]Android kotlin协程浅析笔记

1.协程

协程?我们明确一下这篇文章,我们需要了解什么东西.

1.协程是什么东西
2.协程用来干什么
3.协程怎么写
> 4.你对我的爱有多深

在这里插入图片描述
根据大佬们的理解,协程大概可以理解为.
一种轻量级线程,协程类似于线程,但是它算是一种可以在单线程模式下模拟多线程编程的效果.里面状态中的挂起和恢复和我们的操作系统无关,只和函数有关
区别:线程运行在内核态,协程运行在用户态
总结:Android kotlin中协程是一个线程框架

根据定义得出作用:跟线程差不多的作用, 用来做异步/网络请求

2.协程域的定义

如果运行在Android上,请先引入依赖:

implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.3.9'
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.3.9'

(1).GlobalScope.launch: 顶层协程域,任何地方都可以开始创建,但当应用程序结束时,协程也会跟着一起结束。(Android不常用)

很容易看出,下面的语句中,只有"initDebug 1"被打印,而"initDebug 2"因为程序已经结束而无法被打印出.

这里解释一下delay()函数,这里是让协程延迟指定时间后再运行,是协程特有的。

  fun main(){
        GlobalScope.launch {
            Log.d(TAG, "initDebug: 1")
            delay(1500)
            Log.d(TAG, "initDebug: 2")
        }
        Thread.sleep(1000)  
    }

(2)runBlocking: 协程域.但它可以保证在协程域内所有代码和子协程在没有执行完前一直阻塞当前线程. (相当不常用)
会发现,两条语句都被打印出来了.

  fun main(){
        runBlocking {
            Log.d(TAG, "initDebug: 1")
            delay(1500)
            Log.d(TAG, "initDebug: 2")
        }
        Thread.sleep(1000)  
    }

(3)coroutineScope:作用域。是一个挂起函数,它的作用就是继承外部协程作用于并创建一个子作用域,一般用作在挂起函数内,开启一个子协程域 (常用在于挂起函数内)
解释一下挂起函数,简单理解就是要求这个函数必须执行在协程中的函数

suspend fun oo(){
coroutineScope {
launch {
	}
}

(4).viewModel.viewModelScope.launch: 配合ViewModel使用上的,一个常用分配作用域,因其跟随着Activity/Fragment的生命周期 (非常推荐使用).
看其源码,你们可以看到CoroutineScope类,它返回的就是这么一个对象,这个对象可以使用.lanuch()去随意创建一个成协程

public val ViewModel.viewModelScope: CoroutineScope
    get() {
        val scope: CoroutineScope? = this.getTag(JOB_KEY)
        if (scope != null) {
            return scope
        }
        return setTagIfAbsent(
            JOB_KEY,
            CloseableCoroutineScope(SupervisorJob() + Dispatchers.Main.immediate)
        )
    }

这里可以看到, 这里返回的是Job,这里可以通过cancle(),让协程进入cancle()状态,注意,是cancle状态,而不是直接取消掉这个协程,后面会说到这个点

    val Job = viewModel.viewModelScope.launch {
            oo()
        }
        Job.cancle()

累了吗?累了,来看看图。
在这里插入图片描述

3.协程域内的协程开启

(1).launch: 开启一个协程,返回一个Job对象.
我们这里只用在Androdi上最常用创建协程域的方法进行操作
我们可以来分析一下这里,这里相当于一个父协程内开启了另一个子协程

  val Job = viewModel.viewModelScope.launch {
            val JobChildren =launch {
                Log.d(TAG, "Job1: ")
            }
        }

(2).async: 开启一个线程,返回Deferred对象。会返回代码块内执行的结果.使用await(),获取结果
但它有一个更重要的特性,若代码块内还未执行完毕,await()方法获取结果时会将当前协程阻塞

      val Job = viewModel.viewModelScope.launch {
            val result =async {
                Log.d(TAG, "Time:${System.currentTimeMillis()}")
                //模拟网络请求数据
                delay(1000)
                5+5
            }.await()

            Log.d(TAG, "等待获取结果:${result}")
            Log.d(TAG, "Time:${System.currentTimeMillis()}")
        }

我们这里可以看到,我们在花时间请求数据后,协程会等待返回结果再继续执行下去.可以看到,这里可以说解决了我们痛恨的死亡后调地狱的问题.

D/NemoMainActivity: Time:1639619877149
D/NemoMainActivity: 等待获取结果:10
    Time:1639619878152

4.调度器

有了调度器之后,协程才真正意义上被赋予了灵魂.
这里实现一个功能。
我们知道一般的网络请求,我们会放到异步去执行, 执行完毕后,才回到主线程进行UI操作,那么我们的协程是如何实现的呢?
就是那么简单粗暴,我们可以在开启协程的时,添加线程参数.

Dispatchers.Default:默认的低并发线程策略。
Dispatchers.Main:Android主线程内执行
Dispatchers.IO:高并发线程策略.

 val Job = viewModel.viewModelScope.launch {
            val result =async(Dispatchers.IO) {
                Log.d(TAG, "Time:${System.currentTimeMillis()}")
                //模拟网络请求数据
                delay(1000)
                5+5
            }.await()

            launch(Dispatchers.IO) {
                binding.TestButton2.text = result
                
            }
        }

withContext(),这里提醒一个withContext,它类似于async(),但是这里强制要求我们指定一个线程参数。

 val Job = viewModel.viewModelScope.launch {
            val result =withContext(Dispatchers.IO) {
                Log.d(TAG, "Time:${System.currentTimeMillis()}")
                //模拟网络请求数据
                delay(1000)
                5+5
            }.await()

            launch(Dispatchers.IO) {
                binding.TestButton2.text = result
                
            }
        }

5.应用

根据上面我们所说,我们应该很容易想到了协程的好处,以及我们应用的地方.

(1)网络请求,可以随意切换线程去触发网络请求或者调整UI.并且防止了回调地狱.让写异步代码,读起来像同步一样
(2)并发请求:我们可以在同一个协程域下,开启多个协程,每个协程都去进行网络请求.实现了并发请求~

当然,这里只是最普通的用法,它还可以用来很多很多的地方,与Flow的配合,再加上网络请求框架okhttp+retrofit.就是如虎添翼了.
具体可以看一下我之前的文章
https://blog.csdn.net/qq_33902817/article/details/120290711

另外这里提醒一下,协程使用的是状态管理.如果你要在一个持续任务中cancle掉协程,而延时任务还在进行.cancle是无法直接取消协程的.具体看这个帖子.
https://www.jianshu.com/p/42152d53349a

6.总结

kotlin的协程还是需要我们一个个去掌握的…当然,有一些业务情况下,RXJAVA还是蛮好用的,比如间隔任务之类的.具体任务具体分析嘛~
不过这个是让我不要忘了以及搞混淆kotlin协程之间的关系…我经常搞混0-0~在这里插入图片描述

  移动开发 最新文章
Vue3装载axios和element-ui
android adb cmd
【xcode】Xcode常用快捷键与技巧
Android开发中的线程池使用
Java 和 Android 的 Base64
Android 测试文字编码格式
微信小程序支付
安卓权限记录
知乎之自动养号
【Android Jetpack】DataStore
上一篇文章      下一篇文章      查看所有文章
加:2021-12-18 16:06:39  更:2021-12-18 16:07:33 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 8:27:53-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码