网站伪静态有什么用,有什么好的设计网站,wordpress 微论坛主题,网站推广是什么协程(coroutines)是一种并发设计模式#xff0c;您可以在Android 平台上使用它来简化异步执行的代码。协程是在版本 1.3 中添加到 Kotlin 的#xff0c;它基于来自其他语言的既定概念。
在 Android 上#xff0c;协程有助于管理长时间运行的任务#xff0c;如果管理不当您可以在Android 平台上使用它来简化异步执行的代码。协程是在版本 1.3 中添加到 Kotlin 的它基于来自其他语言的既定概念。
在 Android 上协程有助于管理长时间运行的任务如果管理不当这些任务可能会阻塞主线程并导致应用无响应。使用协程的专业开发者中有超过 50% 的人反映使用协程提高了工作效率。
为什么协程如此重要
协程是 Kotlin 对比 Java 的最大优势。Java 也在计划着实现自己的协程Loom不过这个毕竟还处于相当初级的阶段。而 Kotlin 的协程可以帮我们极大地简化异步、并发编程、优化软件架构。通过协程我们不仅可以提高开发效率还能提高代码的可读性由此也就可以降低代码出错的概率。
协程基本使用
若使用协程首先我们得引入协程相关的开发包
implementation org.jetbrains.kotlinx:kotlinx-coroutines-core:1.3.7-mpp-dev-11
implementation org.jetbrains.kotlinx:kotlinx-coroutines-android:1.3.7-mpp-dev-11
上面一个是java环境的下面一个是android环境下的这里我们都引入进来。
协程最简单的使用我们可以使用GlobalScope.launch去开启一个协程代码如下所示
GlobalScope.launch {Log.d(TAG, Thread.currentThread().name)
}运行结果如下所示 说明这段代码是运行在一个子线程中的当然我们可以在launch中传递参数让他运行在主线程中
GlobalScope.launch(Dispatchers.Main) {Log.d(TAG, Thread.currentThread().name)
}这样里面的这段代码就运行在主线程中了由此可见 协程是什么简单的说就是协程可以让我们开启一个线程是一个线程框架。当然实际项目中开启协程我们不会使用上面的方法。别急我们要循序渐进~
协程和线程相比有什么优势?
协程和线程相比的优势我们直接用一个例子来说明比如当前我们要去请求网络拿到数据后将数据显示出来这里我们模拟两个方法分别为 网络请求获取数据 和 将数据显示在UI上我们定义方法如下:
/*** 从服务器取信息*/
private fun getMessageFromNetwork(): String {
for (i in 0..1000000) {//这里模拟一个耗时操作}
var name Huanglinqingreturn name
}
/*** 显示信息* message :信息*/
private fun showMessage(message: String) {tvName.text message
}由于getMessage是一个耗时操作所以我们将他放在子线程中而在Android中 UI更新操作不能放在子线程中所以我们必须将showMessage方法放在UI线程中在之前我们实现这种需求 只能自己去执行切线程的代码代码如下所示
/*** 从服务器取信息*/
private fun getMessageFromNetwork() {
for (i in 0..1000000) {//这里模拟一个耗时操作}
var name HuanglinqingrunOnUiThread {showMessage(name)}
}在onCreate中执行如下代码
Thread {getMessageFromNetwork()
}.start()这样呢 看起来还好但是如果现在需求改为请求第一个 后 显示出来再请求第二个 显示出来呢代码就是这个样子
private fun getMessageFromNetwork() {
for (i in 0..1000000) {//这里模拟一个耗时操作}var name HuanglinqingrunOnUiThread {showMessage(name)Thread{getMessageFromNetwork1()runOnUiThread{}}.start()}
}依次类推我们可以想到如果请求很多的话第一 代码结构会很难看第二 写着写着就很乱了那么协程就可以很好的解决这个问题下面我们来看使用协程的方式 怎么写。
首先对于一个耗时的操作我们需要将他切换到后台线程执行withContext函数可以构建一个协程作用域他必须在挂起函数或者协程中执行suspend关键字是kotlin为我们提供的 用于标记挂起函数的关键字。我们修改getMessageFromNetwork方法如下:
/*** 从服务器取信息*/
private suspend fun getMessageFromNetwork(): String {
var name withContext(Dispatchers.IO) {for (i in 0..1000000) {//这里模拟一个耗时操作}
name Huanglinqing1111}
return name
}在onCreate中协程中直接这样写
GlobalScope.launch(Dispatchers.Main) {var name getMessageFromNetwork()showMessage(name)
}运行结果如下所示 如果我们有多个请求呢那就再多加几个
GlobalScope.launch(Dispatchers.Main) {var name getMessageFromNetwork()showMessage(name)var name1 getMessageFromNetwork()showMessage(name1)var name2 getMessageFromNetwork()showMessage(name2)
}这样getMessageFromNetwork在后台执行showMessage在前台执行由此看来。
协程比线程的优势在什么地方
1、协程可以帮我们自动切线程
2、摆脱了链式回调的问题
Retrofit 如何使用协程
从Retrofit2.6.0开始retrofit就自动支持协程了这里我们从「聚合数据」上找到一个开放api我们先来看之前我们怎么使用的首先在Apiservice中定义一个接口如下
GET(https://wanandroid.com/article/listproject/0/json)
fun queryData(): CallBaseReqDataDataReqBean在activity中添加如下代码
var retrofit Retrofit.Builder().baseUrl(http://v.juhe.cn/).addConverterFactory(GsonConverterFactory.create()).build()
val apiService retrofit.create(ApiService::class.java)
tvName.setOnClickListener {apiService.queryData(top,04ea095cbea56775e2d1669713f34cc2).enqueue(object :CallbackBaseReqDataNewBean{override fun onFailure(call: CallBaseReqDataNewBean, t: Throwable) {tvName.text t.toString()Log.d(网络请求错误, t.toString())}
override fun onResponse(call: CallBaseReqDataNewBean,response: ResponseBaseReqDataNewBean) {tvName.text response.code().toString()}})这里我们将返回结果的状态码显示在view上运行结果如图所示 上面代码看起来没有什么问题如果我们用到了mvp模式什么的便于职责单一还要单独放一个类中这样就需要添加回调才能获取返回结果。
那么协程中怎么使用呢?
首先我们在ApiService中新增一个函数 声明为挂起函数类型不需要添加Call
GET(toutiao/index)
suspend fun queryDataKotlin(Query(type) type: String?, Query(key) key: String?): BaseReqDataNewBean在onCreate中代码如下所示
GlobalScope.launch(Dispatchers.Main) {try {var result apiService.queryDataKotlin(top, 04ea095cbea56775e2d1669713f34cc2)tvName.text result.toString()}catch (e:Exception){tvName.text e.toString()}
}没错就是这么简单没有什么回调因为queryDataKotlin是一个挂起函数当运行到挂起函数的时候协程会处于等待状态等返回结果后主动切回主线程执行下面的方法。
而try catch的作用就等同于上面onFailure的回调这个时候你可能会说了我去还要写try catch 好low的感觉别忘了协程的另一个优势就是可以减少回调如果仍然有成功方法或者失败方法 那还是走了回调的逻辑
协程提升效率
协程可以提升什么效率假设我们现在有两个接口请求需要等到两个接口都请求完毕的时候 显示出结果如果在之前会怎么样先请求接口1 接口1有结果后再请求结果2而协程可以做到接口1和接口2同时请求等请求结束后将结果合并显示过来这里我们请求统一接口来模拟请求两个不同的接口
GlobalScope.launch(Dispatchers.Main) {try {var result1 async { apiService.queryDataKotlin(top, 04ea095cbea56775e2d1669713f34cc2) }var result2 async { apiService.queryDataKotlin(top, 04ea095cbea56775e2d1669713f34cc2) }tvName.text result1.await().toString() \n\n result2.await().toString()接口2} catch (e: Exception) {tvName.text e.toString()}
}运行结果如下所示 这样本来要分步做的两件事情可以同时做了当然可以提高效率了async函数必须在协程作用域中调用会创建一个新的子协程并返回一个Deferred对象调用这个对象的await方法 就可以获取执行结果。 本文主要解析在Kotlin中的协程简单使用以及和线程的对比优势有关更多的Kotlin技术可以参考《Kotlin手册》学习更多核心技术点可以查看详细类目。 最后
要记住协程的几个 API 很容易困难的是形成一套完整的协程知识体系。其实学习协程相当于一次编程思维的升级。协程思维它与我们常见的线程思维迥然不同当我们能够用协程的思维来分析问题以后线程当中某些棘手的问题在协程面前都会变成小菜一碟。因此我们相当于多了一种解决问题的手段。