首页
学习
活动
专区
圈层
工具
发布
    • 综合排序
    • 最热优先
    • 最新优先
    时间不限
  • 来自专栏算法微时光

    Android Kotlin之withContext(协程)使用

    image.png withContext kotlin 中 GlobalScope 类提供了几个创建协程的构造函数: launch: 创建协程 async : 创建带返回值的协程,返回的是 Deferred 类 withContext:不创建新的协程,指定协程上运行代码块 runBlocking:不是 GlobalScope 的 API,可以独立使用,区别是 runBlocking 里面的 delay 会阻塞线程 并在闭包内的逻辑执行结束之后,自动把线程切回去继续执行: coroutineScope.launch(Dispatchers.Main) { // 在 UI 线程开始 val image = withContext

    4.1K20发布于 2021-01-21
  • 来自专栏Android 开发者

    在 Android 开发中使用协程 | 背景介绍

    由于 withContext 本身就是一个 suspend 函数,它会使用协程来保证主线程安全。 withContext 的性能 withContext 同回调或者是提供主线程安全特性的 RxJava 相比的话,性能是差不多的。 在某些情况下,甚至还可以优化 withContext 调用,让它的性能超越基于回调的等效实现。 如果某个函数需要对数据库进行 10 次调用,您可以使用外部 withContext 来让 Kotlin 只切换一次线程。 这样一来,即使数据库的代码库会不断调用 withContext,它也会留在同一调度器并跟随快速路径,以此来保证性能。

    2K30发布于 2020-04-10
  • 来自专栏Android开发与分享

    【Kotlin】协程(一)——入门

    withContext withContext():用给定的协程上下文调用指定的暂停块,暂停直到完成,然后返回结果。也就是说,可以用来切换线程,并返回执行后的结果。 有withContext()后,线程的切换显得是那么简单。只要你开心,可以切来切去。 mainScope.launch { withContext(Dispatchers.Default) { Logger.i("切到子线程") } withContext 如果切换线程中的代码很多,想把(withContext(){...})的代码抽出来。 发现withContext()只能在协程或suspend方法中使用。所以,在方法前加上suspend就不会报错了。

    1.6K20发布于 2019-10-28
  • 来自专栏大前端修炼手册

    Kotlin协程:理解主要概念

    在Kotlin的协程世界中,我们经常会遇到coroutineScope,CoroutineScope,supervisorScope和withContext这些概念。 2.3 coroutineScope vs withContext 最后,我们来看看coroutineScope和withContextwithContext通常用于在不同的调度器(Dispatcher)之间切换协程的执行线程。 coroutineScope和withContext的区别在于前者用于创建协程作用域和启动子协程,后者用于在不同的协程上下文中执行代码。 最后,coroutineScope和withContext在功能上有所不同,coroutineScope用于创建新的协程作用域并启动子协程,withContext则用于在不同的协程上下文中执行代码。

    41410编辑于 2024-07-23
  • 来自专栏程序员修炼之路

    协程切换引发主线程卡顿?Dispatchers.IO的四个致命误区

    使用率从15%飙升至78% 优化方案: viewModelScope.launch(Dispatchers.Default) { // CPU任务用Default val data = withContext { fetchNetworkData() } // IO操作隔离 updateUI(data) } 二、嵌套陷阱:调度器的多米诺骨牌 误区2:不必要的多级上下文切换 卡顿案例: withContext (Dispatchers.IO) { withContext(Dispatchers.Default) { // 产生额外调度开销 heavyCalculation() 错误实现: fun onClick() { runBlocking(Dispatchers.Main) { // 阻塞主线程等待IO结果 val result = withContext 会完全阻塞当前线程,导致VSYNC信号丢失 • 实测数据:某电商App该写法导致帧率从60FPS暴跌至12FPS 正确异步方案: lifecycleScope.launch { val result = withContext

    50110编辑于 2025-04-22
  • 来自专栏Java与Android技术栈

    Kotlin Coroutines 笔记 (二)

    一. withContext 与 launch、async、runBlocking 类似 withContext 也属于 Coroutine builders。 不过与他们不同的是,其他几个都是创建一个新的协程,而 withContext 不会创建新的协程。 withContext 允许更改协程的执行线程,withContext 在使用时需要传递一个 CoroutineContext 。 而 withContext 可以直接返回。 共享线程池 在上述的例子中,withContext 使用了 CommonPool。CommonPool 继承了 CoroutineDispatcher,表示使用线程池来执行协程的任务。

    1.3K10发布于 2018-08-24
  • 来自专栏韩曙亮的移动开发专栏

    【Kotlin 协程】协程底层实现 ③ ( 结构化并发 | MainScope 作用域 | 取消协程作用域 | Activity 实现 CoroutineScope 协程作用域接口 )

    } 代码示例 : mainScope.launch { // 协程作用域, 在该代码块中执行协程任务 // Dispatchers.IO 是协程任务调度器, 用于执行耗时操作 withContext (Dispatchers.IO){ Log.i("MainActivity", "withContext : 协程中执行耗时操作") } // 挂起函数, 可以不使用协程调度器 (Dispatchers.IO){ Log.i("MainActivity", "withContext : 协程中执行耗时操作") } launch { // 协程作用域, 在该代码块中执行协程任务 // Dispatchers.IO 是协程任务调度器, 用于执行耗时操作 withContext (Dispatchers.IO){ Log.i("MainActivity", "withContext : 协程中执行耗时操作") }

    1.8K11编辑于 2023-03-30
  • 来自专栏程序员修炼之路

    6个Android Kotlin协程相关面试题

    } println("Hello, ") job.join() // 等待协程完成 } 面试题目3:解释Kotlin协程中的withContext是如何工作的,以及它与Dispatchers.IO 解答: withContext是一个挂起函数,它允许你切换协程的上下文(即线程)。 当你需要执行一个耗时的阻塞操作时,可以使用withContext(Dispatchers.IO)来在IO线程上执行该操作,而不阻塞主线程。 withContext接受一个新的上下文(如Dispatchers.IO)作为参数,并在该上下文中执行传递的代码块。当代码块执行完毕后,控制权会返回到原先的上下文中。 .* fun main() = runBlocking { val result = withContext(Dispatchers.IO) { // 模拟耗时的I/O操作

    1.7K10编辑于 2024-11-19
  • 来自专栏Android技术专栏

    Kotlin协程系列(三)

    4.withContext函数的作用   官方框架中还为我们提供了一个好用的api,withContext(),它的定义如下: public suspend fun <T> withContext( context: CoroutineContext, block: suspend CoroutineScope.() -> T ): T   withContext会将参数中的lambda表达式调度到由 并且它会返回协程体当中的返回值,它的作用几乎和async{}.await()等价,但和async{}.await()相比,它的内存开销更低,因此对于使用async后立即要调用await的情况,应当优先使用withContext 而且有了withContext之后,在Android开发的时候,就可以不再使用Handler了,我们可以在需要进行耗时操作(网络请求,数据库读写,文件读写)时,使用withContext切换到IO线程上 lifecycleScope.launch(Dispatchers.IO) { delay(1000) val result="JJLin" withContext

    54910编辑于 2023-12-02
  • 来自专栏码上积木

    协程三问—快手真题

    (Dispatcher.IO){}} suspend fun request2(parameter : Parameter){withContext(Dispatcher.IO){}} suspend fun request3(parameter : Parameter){withContext(Dispatcher.IO){}} 就像是同一个线程中顺序执行的效果一样,再比如我要按顺序执行一次异步任务 updateUI1() updateUI2() updateUI3() } suspend fun ioTask1(){ withContext (Dispatchers.IO){} } suspend fun ioTask2(){ withContext(Dispatchers.IO){} } suspend fun ioTask3(){ withContext(Dispatchers.IO){} } fun updateUI1(){ } fun updateUI2

    66030发布于 2020-10-29
  • 来自专栏seth-shi的专栏

    go-zero 中使用 gorm gen

    , data) } func (l *GormLogger) Error(ctx context.Context, msg string, data ...interface{}) { logx.WithContext = nil { // 记录未找到的错误使用 warning 等级 if errors.Is(err, gorm.ErrRecordNotFound) { logx.WithContext( = 0 && elapsed > l.SlowThreshold { logx.WithContext(ctx).Sloww("Database Slow Log", logFields...) = service.ProMode { logx.WithContext(ctx).Infow("Database Query", logFields...) } } func microsecondsStr WithContext(ctx). Where(do.App.ID.Eq(id)).

    1.5K10编辑于 2023-12-18
  • 来自专栏QQ音乐技术团队的专栏

    资源混淆是如何影响到Kotlin协程的

    withContext(Dispatchers.Main){ textview.text=result } withContext(Dispatchers.Main){ textview.text=result } 那么这是为什么呢? 既然用demo复现了这个问题,那么单步调试一下,看看withContext里面到底挂在了哪里? 'kotlinx-coroutines-android 所以上面withContext里面的代码就没有执行到了。 那么这里的MainDispatcher是什么呢? 原来是在调用withContext来切换线程的时候,会用到类MainCoroutineDispatcher。

    2.3K33发布于 2019-06-03
  • 来自专栏跟着asong学Golang

    并发编程包之 errgroup

    main() { Google := func(ctx context.Context, query string) ([]Result, error) { g, ctx := errgroup.WithContext range results { fmt.Println(result) } } 上面这个例子来自官方文档,代码量有点多,但是核心主要是在Google这个闭包中,首先我们使用errgroup.WithContext context.Context) func (g *Group) Go(f func() error) func (g *Group) Wait() error errGroup总共只有三个方法: WithContext 方法 func WithContext(ctx context.Context) (*Group, context.Context) { ctx, cancel := context.WithCancel 因为这个ctx是WithContext方法返回的一个带取消的ctx,我们把这个ctx当作父context传入WriteChangeLog方法中了,如果errGroup取消了,也会导致上下文的context

    69520编辑于 2022-07-11
  • 来自专栏刘晓杰

    Coroutine(协程)和retrofit

    by CoroutineScope(Dispatchers.Default) MainScope() MainScope其实是专门为UI创建,默认Dispatchers.Main 1.6 切换线程 用withContext use { ctx2 -> runBlocking(ctx1) { log("Started in ctx1") withContext MyDispatcher()) { val data = service.listReposV2("octocat").await() withContext (Dispatchers.Main) { if (isFinishing) {//生命周期 return@withContext (Dispatchers.Main) { if (isFinishing) {//生命周期 return@withContext

    1.6K20发布于 2020-06-02
  • 来自专栏程序员修炼之路

    协程切换引发ANR?Dispatcers.IO线程池饥饿的六种破解姿势

    Default调度器 viewModelScope.launch(Dispatchers.Default) { val data = parseLargeJson(response) withContext (Dispatchers.Main) { updateUI(data) } } 二、嵌套陷阱:调度器的多米诺骨牌 2.1 多级调度引发的雪崩效应 错误代码: withContext(Dispatchers.IO ) { withContext(Dispatchers.Default) { heavyCalculation() } // 额外调度开销 } 源码解析(kotlinx-coroutines-core context[ContinuationInterceptor] as CoroutineDispatcher) .dispatch(context, block) } 性能特征: 每层withContext runBlocking完全阻塞主线程导致VSYNC信号丢失 某电商App该写法导致帧率从60FPS暴跌至12FPS 正确异步方案: lifecycleScope.launch { val result = withContext

    40100编辑于 2025-05-12
  • 来自专栏小柔博客园

    协程简单上手(线程切换)

    典型的场景比如开启协程获取数据需要进行不同的线程切换: 这时候可以使用withContext withContext(Dispatchers.IO) {             // IO线程运行         } 当withContext运行完成之后会自动恢复调用withContext的线程中。 由于多线程下的测试是不可预测的,所以正式编码中出现的withContext切换线程应换成单线程的方式因为这样将会使得结果可预测,所以再项目中不能使用硬编码去设置调度器Dispatchers,应该使用注入的方式如果是测试注入

    88820编辑于 2022-10-09
  • 来自专栏网管叨bi叨

    觉得WaitGroup不好用?试试ErrorGroup吧!

    Go扩展库通过errorgroup.Group提供ErrorGroup原语的功能,它有三个方法可调用: func WithContext(ctx context.Context) (*Group, context.Context ) func (g *Group) Go(f func() error) func (g *Group) Wait() error 调用errorgroup包的WithContext方法会返回一个Group 我们可以用errgroup.Group提供的WithContext方法创建一个带可取消上下文功能的ErrorGroup。 构造器创建errgroup.Group 结构体: func WithContext(ctx context.Context) (*Group, context.Context) { ctx, cancel 在子任务全部完成时会通过调用在errorgroup.WithContext创建Group和Context对象时存放在Group.cancel字段里的函数,取消Context对象并返回可能出现的错误。

    2.1K10发布于 2020-12-31
  • 来自专栏Android 开发者

    协程中的取消和异常 | 驻留任务详解

    将调度器注入到类中 不要在创建协程或调用 withContext 时硬编码调度器。 ✅ 好处: 便于测试。您可以在进行单元测试或仪器测试时轻松替换掉它们。 2. } } class Repository(private val ioDispatcher: CoroutineDispatcher) { suspend fun doWork() { withContext 另一种可以在一些用例中使用的方案 (可能是任何人都会首先想到的方案),便是将 veryImportantOperation 像下面这样用 withContext 封装进 externalScope 的上下文中 (ioDispatcher) { doSomeOtherWork() withContext(externalScope.coroutineContext) { (ioDispatcher) { doSomeOtherWork() withContext(NonCancellable){ veryImportantOperation

    1.9K20编辑于 2022-09-23
  • 来自专栏刘晓杰

    Coroutine(协程)(三)

    volatile 无济于事 @Volatile // 在 Kotlin 中 `volatile` 是一个注解 var counter = 0 fun main() = runBlocking { withContext } } println("Completed ${n * k} actions in $time ms") } fun main() = runBlocking { withContext (Dispatchers.Default) { massiveRun { // 将每次自增限制在单线程上下文中 withContext(counterContext 每个增量操作都得使用 withContext(counterContext) 块从多线程 Dispatchers.Default 上下文切换到单线程上下文。 finally { mutex.unlock() } 模式: val mutex = Mutex() var counter = 0 fun main() = runBlocking { withContext

    67820发布于 2021-03-04
  • 来自专栏程序员修炼之路

    Android面试题之Kotlin 协程的挂起、执行和恢复过程

    .* fun main() = runBlocking { withContext(Dispatchers.Main) { println("Running on main thread : ${Thread.currentThread().name}") withContext(Dispatchers.IO) { println } println("Back to main thread: ${Thread.currentThread().name}") } } 在这个例子中: withContext withContext(Dispatchers.IO) 切换到 I/O 线程,执行 delay 挂起。 挂起后,协程会保存当前状态和上下文,并交由 Dispatchers.IO 管理。 withContext(Dispatchers.Main) 之后的代码切换回主线程,保证恢复到原来的执行环境。

    94310编辑于 2024-06-13
领券