上一篇文章中我们分析了挂起函数的本质(状态机),以及查看编译器为我们生成的类里面是如何借用状态机实现的“挂起”,那么在实际coding中我们该如何使用协程呢?...}当withContext运行完成之后会自动恢复调用withContext的线程中。...协程如何测试开启协程runTest 是用于测试的协程构建器。相比于正式编码的时候使用的是launch和async。使用此构建器可封装包含协程的任何测试。...必须使用指定调度器通过TestDispatchers调度器来指定协程的运行线程,相比于正式编码使用的是Dispatchers.IO,Dispatchers.Main,Dispatchers.Default...由于多线程下的测试是不可预测的,所以正式编码中出现的withContext切换线程应换成单线程的方式因为这样将会**使得结果可预测**,所以再项目中不能使用硬编码去设置调度器Dispatchers,应该使用注入的方式如果是测试注入
theme: condensed-night-purple 上一篇文章中我们分析了挂起函数的本质(状态机),以及查看编译器为我们生成的类里面是如何借用状态机实现的“挂起”,那么在实际coding中我们该如何使用协程呢...典型的场景比如开启协程获取数据需要进行不同的线程切换: 这时候可以使用withContext withContext(Dispatchers.IO) { // IO线程运行 ...协程如何测试 开启协程 runTest 是用于测试的协程构建器。相比于正式编码的时候使用的是launch和async。使用此构建器可封装包含协程的任何测试。...必须使用指定调度器 通过TestDispatchers调度器来指定协程的运行线程,相比于正式编码使用的是Dispatchers.IO,Dispatchers.Main,Dispatchers.Default...由于多线程下的测试是不可预测的,所以正式编码中出现的withContext切换线程应换成单线程的方式因为这样将会使得结果可预测,所以再项目中不能使用硬编码去设置调度器Dispatchers,应该使用注入的方式如果是测试注入
作用域仅在 Activty 中 , 如果 Activity 被销毁 , 则 在 onDestory 生命周期函数中取消协程任务 ; viewModelScope : 该作用与仅在 ViewModel 中使用..., 与 ViewModel 生命周期绑定 ; lifecycleScope : 该作用与仅在 Activity 中使用 , 与 Activity 生命周期绑定 ; 一、MainScope 协程作用域...是协程任务调度器, 用于执行耗时操作 withContext(Dispatchers.IO){ Log.i("MainActivity", "withContext : 协程中执行耗时操作...是协程任务调度器, 用于执行耗时操作 withContext(Dispatchers.IO){ Log.i("MainActivity", "withContext...是协程任务调度器, 用于执行耗时操作 withContext(Dispatchers.IO){ Log.i("MainActivity", "withContext
使用协程来处理协程任务 使用协程可以简化您的代码来处理类似 fetchDocs 这样的耗时任务。我们先用协程的方法来重写上面的代码,以此来讲解协程是如何处理耗时任务,从而使代码更清晰简洁的。...上述动画展示了 Kotlin 如何使用 suspend 和 resume 来代替回调 观察上图中 fetchDocs 的执行,就能明白** suspend** 是如何工作的。...接着前面的示例来讲,您可以使用调度器来重新定义 get 函数。在 get 的主体内,调用 withContext(Dispatchers.IO) 来创建一个在 IO 线程池中运行的块。...由于 withContext 本身就是一个 suspend 函数,它会使用协程来保证主线程安全。...接下来的文章中我们将继续探讨协程在 Android 中是如何使用的,感兴趣的读者请继续关注。
如何理解协程 协程是一种不同于进程和线程的存在,其本质是一种函数,同一线程中的多个协程是串行执行的,但为了理解仍然需要三者一起对比。...在 get 方法的主体内,调用 withContext(Dispatchers.IO) 来创建一个在 IO 线程池中运行的块。放在该块内的任何代码都始终通过 IO 调度器执行。...由于 withContext本身就是一个suspend函数,它会使用协程来保证主线程安全。...// Dispatchers.Main show(result) } // Dispatchers.Main suspend fun get(url: String) = withContext...(Dispatchers.IO) { // Dispatchers.IO } // Dispatchers.Main 为了更好地管理和使用协程,一般要指定协程上下文
image.png withContext kotlin 中 GlobalScope 类提供了几个创建协程的构造函数: launch: 创建协程 async : 创建带返回值的协程,返回的是 Deferred...类 withContext:不创建新的协程,指定协程上运行代码块 runBlocking:不是 GlobalScope 的 API,可以独立使用,区别是 runBlocking 里面的 delay 会阻塞线程...并在闭包内的逻辑执行结束之后,自动把线程切回去继续执行: coroutineScope.launch(Dispatchers.Main) { // 在 UI 线程开始 val image = withContext...(Dispatchers.IO) { // 切换到 IO 线程,并在执行完成后切回 UI 线程 getImage(imageId) // 将会运行在
本主题描述了如何使用Kotlin协程解决这些问题,使您能够编写更清晰,更简洁的应用程序代码。 管理长时间运行的任务 在Android上,每个应用程序都有一个主线程来处理用户界面并管理用户交互。...for `get` show(result) // Dispatchers.Main } suspend fun get(url: String) = withContext(Dispatchers.IO...Dispatchers.IO – 此调度程序已经过优化,可在主线程外执行磁盘或网络I / O. 示例包括使用Room组件,读取或写入文件以及运行任何网络操作。...继续前面的示例,您可以使用调度程序重新定义get函数。 在get的主体内部,调用withContext(Dispatchers.IO)来创建一个在IO线程池上运行的块。...要点:使用使用Dispatchers.IO或Dispatchers.Default等线程池的调度程序并不能保证该块从上到下在同一个线程上执行。
协程,kotlin中一个神奇的组件,由于使用方便任意切换被广大开发者使用,今天就来看看协程: 说说你对协程的理解 说下协程具体的使用 协程怎么取消 说说你对协程的理解 在我看来,协程和线程一样都是用来解决并发任务...kotlin中的协程其实是对线程的一种封装,或者说是一种线程框架,为了让异步任务更好更方便使用。...说下协程具体的使用 比如在一个异步任务需要回调到主线程的情况,普通线程需要通过handler切换线程然后进行UI更新等,一旦多个任务需要顺序调用,那更是很不方便,比如以下情况: //客户端顺序进行三次网络异步请求...(Dispatchers.IO){} } suspend fun ioTask2(){ withContext(Dispatchers.IO){} } suspend...fun ioTask3(){ withContext(Dispatchers.IO){} } fun updateUI1(){ } fun updateUI2
withContext挂起的是内部包裹的代码块,阻塞当前运行withContext的协程。...一个withContext和一个delay都是可以实现挂起,withContext挂起时间取决于包裹的代码块运行时间,delay是直接设置挂起时间,delay挂起阻塞当前运行delay的协程,delay...协程 开始执行,时间: ${System.currentTimeMillis()}") val job1 = withContext(Dispatchers.IO) {...既然都是共享内存那和我们自己使用共享内存有什么区别呢?所以更为准确的说法是为什么我们使用发送消息的方式来同步信息,而不是多个线程或者协程直接共享内存?...1.首先,使用发送消息来同步信息相比于直接使用共享内存和互斥锁是一种更高级的抽象,使用更高级的抽象能够为我们在程序设计上提供更好的封装,让程序的逻辑更加清晰; 2.其次,消息发送在解耦方面与共享内存相比也有一定优势
可以使用 Dispatchers.IO参数把任务切到 IO 线程执行: CoroutineScope(Dispatchers.IO).launch { ... } 也可以使用 Dispatchers.Main...如果只是使用 launch 函数,协程并不能比线程做更多的事。不过协程中却有一个很实用的函数:withContext 。...不过如果只是这样写,编译器是会报错的: fun getImage(imageId: Int) = withContext(Dispatchers.IO) { // IDE 报错 Suspend...是 suspend 函数指定的,比如函数内部的 withContext 传入的Dispatchers.IO所指定的 IO 线程。...(Dispatchers.IO) { ... } 我们可以发现不同之处其实在于 withContext函数。
协程作用域: 理解协程作用域的概念,如何管理多个协程的生命周期和范围。 并发与顺序性: 学会使用协程来处理并发任务和顺序性操作,以及如何组合多个协程的执行流程。...launch { val result = withContext(Dispatchers.IO) { // 在IO线程上执行异步操作 } // 在UI线程处理结果...下面将深入介绍如何使用协程来处理并发任务和顺序性操作,以及如何在不同的场景中组合多个协程的执行流程。 并发任务 协程使并发任务的管理变得非常直观。...runBlocking { val result = withContext(Dispatchers.IO) { fetchFromDatabaseAsync()...下面将介绍如何在Android应用中使用协程处理UI操作,确保用户界面的流畅和响应。
it.setOnClickListener { // 创建协程 GlobalScope.launch { // Dispatchers.IO...是协程任务调度器, 用于执行耗时操作 withContext(Dispatchers.IO){ Log.i("MainActivity...", "withContext : 协程中执行耗时操作") } // 主线程更新 UI...是协程任务调度器, 用于执行耗时操作 withContext(Dispatchers.IO){ Log.i("MainActivity...", "withContext : 协程中执行耗时操作") } // 主线程更新 UI
请看下面代码示例: 1 private suspend fun get(url: String) = withContext(Dispatchers.IO) { 2 // to do...再来看上面的示例 1 private suspend fun get(url: String) = withContext(Dispatchers.IO) { 2 // to do...withContext方法,对该方法传入Dispatchers.IO,使得它闭包下的任务都处于IO线程中,同时witchContext也是一个suspend函数。...那么Coroutine又该如何创建呢?...1 fun getAll() { 2 viewModelScope.launch { 3 val articleList = withContext(Dispatchers.IO
请看下面代码示例: private suspend fun get(url: String) = withContext(Dispatchers.IO) { // to do...再来看上面的示例 private suspend fun get(url: String) = withContext(Dispatchers.IO) { // to do network...withContext方法,对该方法传入Dispatchers.IO,使得它闭包下的任务都处于IO线程中,同时witchContext也是一个suspend函数。...那么Coroutine又该如何创建呢?...fun getAll() { viewModelScope.launch { val articleList = withContext(Dispatchers.IO
这次使用到的是 协程+ retrofit +mvvm的模式,我这儿直接用一个简单的demo来看一下具体的实现方式吧。...,所以这儿将Call换成了Deferred 3.发起请求 ~~~ GlobalScope.launch(Dispatchers.Main) { withContext(Dispatchers.IO...(Dispatchers.IO){ // delay(10000) repository.getDatas() } datas.value...= result } 每一次都需要写个withContext(),实际运用中,感觉有点不方便,于是乎想了一下,怎么才能给他封进请求方法里面?...(Dispatchers.IO){ call.invoke()} } } 通过在BaseRepository里面写了一个专门的请求方法,这样每次只需执行request就行了 请求参考如下 class
“和kotlin的协程相比如何”等。...mainScope.launch { val productInfo = withContext(Dispatchers.IO) { // 1.获取产品信息 GetProductInfoProcessor...logger, productId).process() } val factory = withContext(Dispatchers.IO) { // 2.查询可生产的工厂...var product = factory.produce(productInfo) product = withContext(Dispatchers.IO) { // 4.送去市场部门评估售价...mainScope.launch { // 1.获取商品简要信息 val briefInfo = withContext(Dispatchers.IO) { GetBriefInfoProcessor
挂起函数线程切换 从上面看我们已经挂起了函数,让程序脱离当前的线程,kotlin 协程提供了一个 withContext() 方法,来实现线程切换。..., suspend fun launch() { withContext(Dispatchers.IO){ Log.e("test2", Thread.currentThread...) { Log.e("test", "launch_start") delay(3000) withContext(Dispatchers.Main){...join() Log.e("test", "end") } private suspend fun launch() { withContext(Dispatchers.IO){...使用 GlobalScope 单例对象创建: GlobalScope.launch { ... } GlobalScope和使用 runBlocking 的区别在于不会阻塞线程。
Log.e("协程","我们使用async启动了一个协程") } 作用域 CoroutineScope(Dispatchers.IO).launch { } 和 GlobalScope.launch...(Dispatchers.IO){ } 这两种方式都是在指定的 IO 调度器中启动一个协程,但它们之间有一些区别: GlobalScope.launch(Dispatchers.IO){} 是在全局范围内启动一个协程...UI,例如Android中的主线程 Unconfined:非受限调度器,无所谓调度器,当前协程可以运行在任意线程上 GlobalScope的协程调度器是Dispatchers.Default,那么我们如何改变呢...Kotlin给我们提供了一个顶层函数withContext用于改变协程的上下文并执行一段代码。...() -> T ): T 示例: GlobalScope.launch(Dispatchers.Main) { val result = withContext(Dispatchers.IO)
1、使用账号密码去获取token 2、通过token获取用户信息 很明显,这是个嵌套的请求。...launch 使用launch()创建一个协程,会返回一个Job对象。...常用的有 Dispatchers.Main:工作在主线程中 Dispatchers.Default:将会获取默认调度器(子线程) Dispatchers.IO:IO线程 Dispatchers.Unconfined...(Dispatchers.Main) { Logger.i("切到主线程") } withContext(Dispatchers.IO) { Logger.i...发现withContext()只能在协程或suspend方法中使用。所以,在方法前加上suspend就不会报错了。
示例: lifecycleScope默认主线程,可以通过withContext来指定线程。...lifecycleScope.launch { // do withContext(Dispatchers.IO) { // do } } // or lifecycleScope.launch...(Dispatchers.IO){ // do } // or lifecycleScope.launch { whenResumed { // do } }...author:yechaoa 2、如何知道在某个生命周期去执行协程 以lifecycleScope.launchWhenResumed为例,一探究竟。...以上,就是lifecycleScope的使用,以及执行流程的具体分析。
领取专属 10元无门槛券
手把手带您无忧上云