赞
踩
1)协程是什么?
2)协程和线程的关系?
3)协程如何使用?切线程是什么
4)挂起函数是什么?
5)withContext和lanuch的区别在哪里?
6)Defualt、IO和Main的区别
7)lifecycleScope
协程就是用线程来实现的并发管理库,简单来说就是对线程的封装。那么他的作用是什么?
下面我们来看看一个例子。
以前java
Thread {
//进行耗时操作:比如Http操作
var user = api.getUser()
runOnUiThread {
tvName.text = user.getName()
//处理后,切换到UI线程,将数据显示出来。
}
}.start()
现在协程
CoroutineScope(Dispatchers.Main).launch {
var user = api.getUser()
tvName.text = user.getName()
}
以前我们要进行一些耗时操作,需要另外起来一个线程,线程处理后,如果要将数据回显到UI,还需要使用方法切换的UI线程。然而,如果使用了协程,这些步骤全部都被封装了起来,我们可以用串行的方式写并行的代码。
通过下面这张图,我们可以看到,协程是在线程里面的,就像线程和进程的关系一样。
为什么要切线程:因为我要执行耗时操作。
切线程一般两种:
那么如何切换呢?
CoroutineScope(Dispatchers.IO).launch {
...
}
val coroutineScope = CoroutineScope(Dispatchers.Main)
coroutineScope.launch(Dispatchers.Main) { // 在 UI 线程开始
withContext(Dispatchers.IO) { // 切换到 IO 线程
//getImage(imageId) // 在 IO 线程执行
}
textView.text = "asdfasdfasdf" // 回到 UI 线程更新 UI
}
// 在UI线程上执行操作 CoroutineScope(Dispatchers.Main).launch { // 更新UI组件 textView.text = "Hello,!" } // 在IO线程上执行网络请求 CoroutineScope(Dispatchers.IO).launch { val result = performNetworkRequest() withContext(Dispatchers.Main) { // 在UI线程上更新UI组件 textView.text = result } } // 在默认的调度器上执行计算密集型任务 CoroutineScope(Dispatchers.Default).launch { val result = performComplexCalculation() withContext(Dispatchers.Main) { // 在UI线程上更新UI组 textView.text = result.toString() } }
挂起函数是什么?
他其实就是暂停的意思。就是他执行这个函数的时候,协程就被挂起,协程函数给到其他线程执行,所在的协程就暂停了,执行完后,挂起函数后面的代码才会执行。
挂起的本质就是,协程和线程脱离,暂时不占用线程了,你可以去做别的事情了。协程在其他线程执行完,再切回来。
挂起函数必须在协程里面才能使用,不然挂起谁。
下面我们来看一个例子。
(1)比如我们现在需要发起一个请求
interface HomeApiService { /** * 获取首页Banner数据 * * @return BaseResponse<List<BannerBean>> Banner列表 */ @GET("banner/json") suspend fun getBanners(): BaseResponse<List<BannerBean>> //suspend: 表示这是一个挂起函数,可以在协程中调用,并可以在执行过程中挂起。 /** * 获取置顶文章 * @return BaseResponse<MutableList<ArticleBean>> 置顶文章列表 */ @GET("article/top/json") suspend fun getTopArticle(): BaseResponse<MutableList<ArticleBean>> /** * 根据页面获取分页的文章数据 * @param page Int 获取的文章页码 从 0 开始 * @return BaseResponse<ArticlePageBean> */ @GET("article/list/{page}/json") suspend fun getArticleByPage(@Path("page") page: Int): BaseResponse<ArticlePageBean> }
(2)发起请求
val coroutineScope = CoroutineScope(Dispatchers.Main)
coroutineScope.launch(Dispatchers.IO) {
var result = HomeApiService.getBanners()
showResult(result)
}
HomeApiService.getBanners()这里会挂起,等结果返回后,执行showResult方法。
lanuch开启的是并行的切线程,withContext则是串行,也就是withContext其实也是一个挂起函数,后面的代码会等待前面的代码执行完成。而lanuch则不会。
lifecycleScope,是什么?直接再activity里面了。可以直接调用。
他的特点:
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。