1.3-协程基础与关键知识:手动切线程-withContext

使用 withContext 串行切线程

我们知道启动一个协程是使用 CoroutineScope 的 launch 启动,launch 开启的是并行的切线程:

CoroutineScope(Dispatchers.Main).launch {
	println("Test: 1 - launch + ${Thread.currentThread().name}")
	// 开启了另一个协程,不会等待这个协程执行完就会继续执行下一行代码
	launch(Dispatchers.IO) {
		Thread.sleep(2000)
		println("Test: 2 - withContext + ${Thread.currentThread().name}")
	}
	println("Test: 3 - launch + ${Thread.currentThread().name}")
}

输出结果:
Test: 1 - launch + main
Test: 3 - launch + main
Test: 2 - withContext + DefaultDispatcher-worker-2

上面是在主线程启动了一个协程,然后在它内部也开启了一个协程,因为并行的关系,内部的协程调用 launch 后会直接执行下面的代码,并不会等待内部协程运行完才执行后面的代码。

很多时候我们还会需要串行的切线程,即希望启动的协程能等到执行结束后再执行后面的代码,这时候就需要 withContext

withContext 是一个挂起函数,所以它只能在协程或另一个挂起函数上运行;我们使用 withContext 实现串行代码执行:

CoroutineScope(Dispatchers.Main).launch {
	println("Test: 1 - launch + ${Thread.currentThread().name}")
	withContext(Dispatchers.IO) {
		Thread.sleep(2000)
		println("Test: 2 - withContext + ${Thread.currentThread().name}")
	}
	println("Test: 3 - launch + ${Thread.currentThread().name}")
}

输出结果:
Test: 1 - launch + main
Test: 2 - withContext + DefaultDispatcher-worker-2
Test: 3 - launch + main

在实际项目中也很常用,比如先网络请求拿到数据,然后处理数据,最后显示在界面,就可以这么写:

viewModelScope.launch {
	val data = withContext(Dispatchers.IO) {
		// 网络请求
		"data"
	}
	val processedData = withContext(Dispatchers.Default) {
		// 处理数据
		"processed $data"
	}
	println("Processed data: $processedData")
}

withContext 从名字来看是 [我要基于我给出的 Context 来执行代码] 的意思,这里的 Context 是指的 CoroutineContext,也就是说 withContext 是用来临时切换 CoroutineContext 的而不只是切线程

自定义挂起函数

我们都知道用 suspend 关键字声明一个函数就是挂起函数,那我们什么时候会需要这样自定义一个挂起函数呢?一般是在我们项目代码中用到了挂起函数,因为挂起函数只能在另一个挂起函数调用,不然 IDE 就会报错给我们提示:

在这里插入图片描述

所以自定义挂起函数正确的方式是:我需要一个挂起函数,因为代码需要用到别的挂起函数,所以我需要给函数加上 suspend 关键字声明为挂起函数。声明为挂起函数会限制函数的使用范围,就要遵循 kotlin 的规则来使用。

并不存在 [挂起函数怎么写] 这个想法,而是你在写自定义函数的时候,如果里面会用到别的挂起函数,IDE 给我们提示要加上,那就给这个函数加上 supsend;如果函数代码内部没有调用挂起函数,那就不要加 suspend 声明。这个行为是半自动的有 IDE 辅助。

总结

  • 串行的切线程使用 withContext,实际上 withContext 是用来临时切换 CoroutineContext 的而不只是切线程

  • 自定义挂起函数正确的方式是:我需要一个挂起函数,因为代码需要用到别的挂起函数,所以我需要给函数加上 suspend 关键字声明为挂起函数

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值