一.协程介绍

1.简介

协程是一种并发设计模式,您可以在 Android 平台上使用它来简化异步执行的代码。协程是在版本 1.3 中添加到 Kotlin 的,它基于来自其他语言的既定概念。

在 Android 上,协程有助于管理长时间运行的任务,如果管理不当,这些任务可能会阻塞主线程并导致应用无响应。使用协程的专业开发者中有超过 50% 的人反映使用协程提高了工作效率。本主题介绍如何使用 Kotlin 协程解决以下问题,从而让您能够编写出更清晰、更简洁的应用代码。

2.特点

协程是我们在 Android 上进行异步编程的推荐解决方案。值得关注的特点包括:

  • 轻量:您可以在单个线程上运行多个协程,因为协程支持挂起,不会使正在运行协程的线程阻塞。挂起比阻塞节省内存,且支持多个并行操作。
  • 内存泄漏更少:使用结构化并发机制在一个作用域内执行多项操作。
  • 内置取消支持:取消操作会自动在运行中的整个协程层次结构内传播。
  • Jetpack 集成:许多 Jetpack 库都包含提供全面协程支持的扩展。某些库还提供自己的协程作用域,可供您用于结构化并发。

二.协程的简单应用

1.用协程写Retrofit案例

先导入依赖

 //协程依赖
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.5.0-RC-native-mt'
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.5.0-RC-native-mt'
//retrofit依赖
implementation 'com.squareup.retrofit2:retrofit:2.9.0'
implementation 'com.squareup.retrofit2:converter-moshi:2.9.0'
//实体类
data class User(val `data`: List<Data>,val errorCode: Int,val errorMsg: String
)data class Data(val category: String,val icon: String,val id: Int,val link: String,val name: String,val order: Int,val visible: Int
)
//Retrofit网络请求
val userServiceApi: UserServiceApi by lazy {val retrofit = Retrofit.Builder().client(OkHttpClient.Builder().addInterceptor {it.proceed(it.request()).apply {Log.d("jason", "request:${code()}")}}.build()).baseUrl("https://www.wanandroid.com/friend/").addConverterFactory(MoshiConverterFactory.create()).build()retrofit.create(UserServiceApi::class.java)
}interface UserServiceApi {@GET("json")//挂起suspend fun  User() :User}
class MainActivity2 : AppCompatActivity() {override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)setContentView(R.layout.activity_main)text.text="Jack"button.also {it.setOnClickListener {// 协程构建器         主线程GlobalScope.launch(Dispatchers.Main) {//任务调度器    子线程val user=  withContext(Dispatchers.IO){userServiceApi.User()}text.text="address:${user?.data?.get(0)?.category}"}}}}
}

到此这个例子结束了,接下来我们一 一解释。

2.协程的挂起与恢复

常规函数基础操作包括:invoke(或call)和return,协程新增了suspend和res
ume:
suspend 也称为挂起或暂停,用于暂停执行当前协程,并保存所有局部变量;
resume 用于让已暂停的协程从其暂停处继续执行。

class MainActivity3 : AppCompatActivity() {override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)setContentView(R.layout.activity_main)text.text="Jack"button.also {it.setOnClickListener {// 协程构建器         主线程GlobalScope.launch(Dispatchers.Main) {//挂起方法  getUser()}}}}//挂起关键字private suspend fun getUser(){val  user=get()show(user)}private fun show(user:User){text.text="address:${user?.data?.get(0)?.category}"}                                    //任务调度器    子线程private suspend fun get()=  withContext(Dispatchers.IO){userServiceApi.User()}
}

通过使用suspend 修改后的代码, 需要注意子方法用suspend 父方法也得加suspend 。还用suspend 关键字只能在协程内或其他挂起函数内使用.

3.挂起与阻塞

class MainActivity4 : AppCompatActivity() {override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)setContentView(R.layout.activity_main)text.text="Jack"//挂起不会阻塞主线程,而且会把你所去要的任务记录下来并完成button.also {it.setOnClickListener {// 协程构建器         主线程GlobalScope.launch(Dispatchers.Main) {//延迟  有挂起的作用delay(10000)Log.d("delay","${Thread.currentThread().name} after delay")}//sleep会阻塞主线程,
//                Thread.sleep(10000)
//               Log.d("delay","${Thread.currentThread().name} after sleep")}}}
}

这里通过使用delay,你每点一次按钮都会开一个协程发起一次任务,过10秒后你点了多少下会打印多少次,而且并没有阻塞主线程。而底下的sleep会阻塞主线程,有ANR的危险。

4.协程的基础写法

class MainActivity5 : AppCompatActivity() {/*** */override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)setContentView(R.layout.activity_main)text.text="Jack"//这个是协程底部基础函数//协程体  也是挂起函数val createCoroutine = suspend {5  //传入的值}.createCoroutine(object : Continuation<Int> {//协程上下文override val context: CoroutineContext = EmptyCoroutineContext//协程执行完成的回调override fun resumeWith(result: Result<Int>) {//result 协程执行结果Log.i("resumeWith", "$result ")}})//启动协程createCoroutine.resume(Unit)}
}

5.协程的调度器

所有协程必须在调度器中运行。

Dispatchers.Main : Android上的主线程用来处理UI交互和一些轻量级任务

Dispatchers.IO : 非主线程专为磁盘和网络IO进行了

Dispatchers.Default : 非主线程转为CPU密集型任务进行了优化

6.任务泄露

当某个协程任务丢失,无法追踪,会导致内存、CPI-R磁盘等资源浪费,甚至发
送一个无用的网络请求,这种情况称为任务泄漏
为了能够避免协程泄漏,Kot|in引入了结构化并发机制

1.结构化并发

使用结构化并发可以做到:
取消任务 :当某项任务不再需要时取消它。
追踪任务 :当任务正在执行是,追踪它。                                                                                      发出错误信号:当协程失败时,发出错误信号表明有错误发生。

7.CoroutineScope

定义协程必须指定其CoroutineScope,它会跟踪所有协程,同样它还可以取消
由它所启动的所有协程。

常用的相关API有:
GlobalScope,生命周期是process级别的,即使Activity或Fragment已经被销毁,协程仍然在执行。
MainScope,在Activity中使用,可以在onDestroy()中取消协程。
viewModeIScope,只能在ViewM0de|中使用,绑定ViewM0de|的生命周期。
IifecycIeScope,只能在Activity、Fragment中使用,会绑定Activity和Fragment的生命周期。

class MainActivity6 : AppCompatActivity() {private var nametext :TextView?=null;private var mainScope = MainScope()override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)setContentView(R.layout.activity_main)//text.text="Jack"nametext=findViewById(R.id.text)button.apply {setOnClickListener {mainScope.launch {//User函数用了挂起所以他会自动启用一个子线程请求val user = userServiceApi.User()nametext?.text="address:${user?.data?.get(0)?.category}"}}}override fun onDestroy() {super.onDestroy()//取消mainScope的任务mainScope.cancel()}
}

还可以这么写

class MainActivity6 : AppCompatActivity(),CoroutineScope by MainScope() {private var nametext :TextView?=null;override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)setContentView(R.layout.activity_main)nametext=findViewById(R.id.text)button.apply {setOnClickListener {            launch {//User函数用了挂起所以他会自动启用一个子线程请求val user = userServiceApi.User()nametext?.text = "address:${user?.data?.get(0)?.category}"}}}}override fun onDestroy() {super.onDestroy()//取消mainScope的任务cancel()}
}

这是两种MainScope的两种写法

三.协程上手

这里写一个例子使用:协程+Retrofit+ViewModel+LiveData+DataBinding

在先说明,数据类和Retrofit的封装类和第一个列子使用的使用一个.

先配置DataBinding与依赖

android {dataBinding {enabled = true}
}
    implementation 'com.squareup.retrofit2:retrofit:2.9.0'implementation 'com.squareup.retrofit2:converter-moshi:2.9.0'implementation "androidx.activity:activity-ktx:1.1.0"implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:2.2.0"implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.5.0-RC-native-mt'implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.5.0-RC-native-mt'
class UserRepository{//挂起函数  返回数据suspend fun getUser():User{return userServiceApi.User()}
}
class MainViewModel : ViewModel() {val userLiveData= MediatorLiveData<User>()private val UserRepository=UserRepository()fun getUser(){//viewModelScope 绑定viewModel的生命周期viewModelScope.launch {userLiveData.value= UserRepository.getUser()}}
}
<layout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:app="http://schemas.android.com/apk/res-auto"xmlns:tools="http://schemas.android.com/tools"><data><variablename="viewModel"type="com.example.ktolincorutine.viewModel.MainViewModel" /></data><androidx.constraintlayout.widget.ConstraintLayoutandroid:layout_width="match_parent"android:layout_height="match_parent"tools:context=".MainActivity"><TextViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:text="@{viewModel.userLiveData.data.get(0).category}"android:id="@+id/text"app:layout_constraintBottom_toBottomOf="parent"app:layout_constraintLeft_toLeftOf="parent"app:layout_constraintRight_toRightOf="parent"app:layout_constraintTop_toTopOf="parent" /><Buttonandroid:id="@+id/button"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_marginBottom="224dp"android:text="Button"app:layout_constraintBottom_toBottomOf="parent"app:layout_constraintEnd_toEndOf="parent"app:layout_constraintHorizontal_bias="0.52"app:layout_constraintStart_toStartOf="parent" /></androidx.constraintlayout.widget.ConstraintLayout>
</layout>
class MainActivity7 : AppCompatActivity() {private val mainViewModel:MainViewModel by  viewModels()override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)val binding =DataBindingUtil.setContentView<ActivityMainBinding>(this, R.layout.activity_main)binding.lifecycleOwner=this;binding.viewModel=mainViewModeltext.text="Jack"binding.button.setOnClickListener {mainViewModel.getUser()}}
}

演示:

Kotlin协程 - - - 协程的简单使用相关推荐

  1. AndroidSDK开发6我用kotlin协程写了一个简单sdk

    目录 AndroidSDK开发6我用kotlin协程写了一个简单sdk 1.kotlin的依赖和导包如下:(//如果不使用协程可以去掉协程的导包减少sdk包大小) 2.Application代码如下: ...

  2. swoole mysql 协程_swoole-orm: 基于swoole的mysql协程连接池,简单封装。实现多个协程间共用同一个协程客户端。参考thinkphp-orm...

    swoole-orm 基于swoole的mysql协程连接池,简单封装. 实现多个协程间共用同一个协程客户端 感谢完善 [1]:nowbe -> 新增数据返回insert_id 版本 v0.0. ...

  3. 抽丝剥茧聊Kotlin协程之协程与线程之间的区别

    1. 前言 关于协程,可能大家最经常听到的一句话就是"协程是轻量级的线程".一脸懵逼,有没有?这可是官方的slogan,严格意义上讲,一方面官方是想让大家把协程和线程产生一个直观关 ...

  4. 进程 线程 协程_进程 线程 协程 管程 纤程 概念对比理解

    不知道是不是我自己本身就有那么一丝丝的密集恐惧,把这么一大堆看起来很相似很相关的概念放在一起,看起来是有点麻,捋一捋感觉舒服多了. 相关概念 任务.作业(Job,Task,Schedule) 在进程的 ...

  5. Windows 纤程/协程

    Windows下 纤程/协程 理论知识,立足根本 使用须知 代码 写这篇文章的原因是,很多框架/库都有协程/纤程的支持,比如python的gevent,PHP 的swoole等等,但是具体是什么样的呢 ...

  6. linux多线程编程和linux 2.6下的nptl,Linux多線程編程和Linux 2.6下的NPTL

    這幾天由於工作需要,琢磨了一下Linux下的多線程的相關資料.Linux下最常用的多線程支持庫為Pthread庫,它是glibc庫的組成部分.但是關於Pthread的說明文檔非常缺乏,特別是對POSI ...

  7. 请注意了!你的APP可能有下架风险,途牛同程携程等多款App登黑榜!

    不知道大家是否还记得,去年闹得沸沸扬扬的FaceBook泄漏用户隐私的案子,不清楚的呢?就再带你们吃吃这个瓜.事情是这样的,美国联邦贸易委员会(FTC)在2018年爆料,特朗普在竞选总统期间,聘请的咨 ...

  8. Retrofit+kotlin Coroutines(协程)+mvvm(Jetpack架构组件)实现更简洁的网络请求

    前言 使用kotlin协程也有一段时间了,给我最大的感受就是完全可以替代Rxjava了,并且写起来更加的简洁. 6月份Retrofit发布的2.6.0版本内部支持了kotlin协程中的挂起(suspe ...

  9. python协程异步原理_简单介绍Python的Tornado框架中的协程异步实现原理

    Tornado 4.0 已经发布了很长一段时间了, 新版本广泛的应用了协程(Future)特性. 我们目前已经将 Tornado 升级到最新版本, 而且也大量的使用协程特性. 很长时间没有更新博客, ...

最新文章

  1. 求长度的另一种方法(+obj).Length
  2. eclipse 国际化 $NON-NLS-1$ 含义
  3. 前端学习(1614):oracle数据库管理
  4. MySQL查询结果条数编号示例 mysql 查找结果中自动加序号列
  5. Gartner分享物联网和智慧城市最新数据
  6. linux ps 显示不了中文,enscript转txt为ps文件时中文变成乱码
  7. 信息学奥赛一本通(2067:【例2.5】圆)
  8. 由Object.prototype.toString.call( )引发关于toString( )方法的思考
  9. VM安装CentOs7虚拟机后无法上网之解决方法
  10. 汇编语言(王爽)第四版检测点2.2答案
  11. 慧林系统多服务器授权,慧林虚拟主机管理系统
  12. 丹麦为NSA开绿灯 通过通信中心监控欧洲政客
  13. 互动投影游戏加密狗复制教程!
  14. Linux中格式化(擦除)DVD + RW / DVD-RW磁盘
  15. python nonetype iterable_无法解决“NoneType”对象不是iterable类型
  16. 【转】刨根究底字符编码之八——Unicode编码方案概述
  17. 我的世界服务器vip账号和密码是多少,我的世界hypixel服务器会员有什么区别 hypixel服务器会员介绍...
  18. 【转】激励循环——加密算法如何实际修复现有激励循环
  19. win10照片查看器_非常好用的19个Win10小技巧,学会之后事半功倍
  20. Android版简历(四)

热门文章

  1. 极具职场竞争力的操作系统背景知识学习笔记(Windows+Linux)
  2. 已拿腾讯offer分享面试经历(含解析答案、推荐书籍、资料分享)
  3. 神州租车确定将从港股退市:上半年亏43亿元,联想控股彻底退出
  4. 如何以创新驱动增长战略
  5. 超级高铁原型机现身迪拜,时速高达1200公里!
  6. linux命令中的merge(2)
  7. ubuntu 下语系编码转换
  8. 什么是瞬时极性法,怎么使用?
  9. 桥牌坐庄训练bm2000 level3闯关记录——A2
  10. 信息安全专家李钊博士:信息物理系统安全威胁