Android 使用 kotlin 协程
我写这篇blog的原因是网上很多都是用的coroutines旧版本,但正式版本进行了修改。因为我也是才开始学习coroutines,因此只涉及使用。
第一步:添加依赖
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.1.0'
在我写的时候,kotlinx-coroutines-android:1.1.0版本,是Kotlin 1.3.11版本的配套版本。若是再低版本中,coroutines处于试验状态,需要添加以下代码
kotlin { experimental { coroutines 'enable' } }
第二步 :activity_main.xml 布局
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" tools:context=".MainActivity"> <ImageView android:visibility="gone" android:id="@+id/image" android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="1"/> <TextView android:id="@+id/tvContent" android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="1"/> <TextView android:id="@+id/tvGetPic" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_margin="20dp" android:layout_gravity="center" android:textSize="20sp" android:text="获取" /> </LinearLayout>
第三步:MainActivity.kt
private val UI: CoroutineContext = Dispatchers.Main override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) tvGetPic.setOnClickListener { getText() } } } //方法一: fun getText1(){ val job = GlobalScope.launch(Background) { var str = "" val client = OkHttpClient() val request = Request.Builder() .url("http://www.wanandroid.com/friend/json") .build() val response = client.newCall(request).execute() response.run { body()?.let { val ins = it.string() str= ins } } launch(UI) { tvContent.text = str } } } //方法二: fun getText2(){ val deferred = GlobalScope.async { var str = "" val client = OkHttpClient() val request = Request.Builder() .url("http://www.wanandroid.com/friend/json") .build() val response = client.newCall(request).execute() response.run { body()?.let { val ins = it.string() str = ins } } str } runBlocking { tvContent.text = deferred.await() } }
Dispatchers.Main为Android应用程序提供上下文 ——官方文档
launch { // 运行在父协程的上下文中,即 runBlocking 主协程 println("main runBlocking : I'm working in thread ${Thread.currentThread().name}") } launch(Dispatchers.Unconfined) { // 不受限的——将工作在主线程中 println("Unconfined : I'm working in thread ${Thread.currentThread().name}") } launch(Dispatchers.Default) { // 将会获取默认调度器,共享的后台线程池 println("Default : I'm working in thread ${Thread.currentThread().name}") } launch(newSingleThreadContext("MyOwnThread")) { // 将使它获得一个新的线程 println("newSingleThreadContext: I'm working in thread ${Thread.currentThread().name}") }
Dispatchers.Default——将会获取默认调度器,共享的后台线程池
kotlin中文网链接
效果图:
协程共有三种方式:
- runBlocking:在主线程中调用了 runBlocking, 阻塞 会持续到 runBlocking 中的协程执行完毕。
2.launch:
val job = GlobalScope.launch(Background) { //代码块..... }
launch会返回一个job,这个job是可以被取消的,可以和Android activity,fragment的生命周期联系起来。
在上面中出现了这样一段代码:
fun getText1(){ val job = GlobalScope.launch(Background) { var str = "" val client = OkHttpClient() val request = Request.Builder() .url("http://www.wanandroid.com/friend/json") .build() val response = client.newCall(request).execute() response.run { body()?.let { val ins = it.string() str= ins } } launch(UI) { tvContent.text = str } } }
两次使用launch的方式不同,因为本质上,协程是轻量级的线程。 它们在 CoroutineScope 上下文中和 launch 协程构建器 一起被启动。 这里我们在 GlobalScope 中启动了一些新的协程,存活时间是指新的协程的存活时间被限制在了整个应用程序的存活时间之内。第二次的launch活动范围被限制在第一个之中 。
- async :
val deferred = GlobalScope.async { var str = "" val client = OkHttpClient() val request = Request.Builder() .url("http://www.wanandroid.com/friend/json") .build() val response = client.newCall(request).execute() response.run { body()?.let { val ins = it.string() str = ins } } str } runBlocking { tvContent.text = deferred.await() }
async 与launch的区别在于,async 可以返回获取的值。例如网络请求,不依赖回调接口就可以将获得的数据返回。
与launch一样,async也是可以被取消的
我自己也是刚刚开始学习,如果有什么问题,可以在评论中指出来。
帮助:
1.kotlin中文文档 https://www.kotlincn.net/docs/reference/
2.https://www.jianshu.com/p/04f28bbc66dc
- Android中使用Kotlin协程(Coroutines)和Retrofit进行网络请求(一)
- Android中使用Kotlin协程(Coroutines)和Retrofit进行网络请求(三)之异常处理与封装
- Android中使用Kotlin协程(Coroutines)和Retrofit进行网络请求(二)之文件下载
- 使用Kotlin开发Android
- 使用Kotlin开发Android应用(II):创建新工程
- 让你的代码量减少3倍!使用kotlin开发Android(三) 缩短五倍的Java Bean
- 使用Kotlin开发Android应用(IV):自定义视图和Android扩展
- 让你的代码减少三倍!使用kotlin开发Android(五) 监听器
- 使用Android Studio+Kotlin开发
- 使用Kotlin优雅的开发Android
- [Android]使用Kotlin开发Android(二)
- 使用Kotlin进行Android开发
- 使用Kotlin开发Android遇到的问题
- 【Android】使用Kotlin在Android Studio上开发App
- 让你的代码量减少3倍!使用kotlin开发Android(四) kotlin bean背后的秘密
- 使用Kotlin开发Android应用
- kotlin 开发 android 程序中网络http请求和线程的使用
- 使用 Android Studio 为 Android 创建一个简单的 Kotlin 应用程序
- 使用Kotlin进行Android开发
- 使用Kotlin开发Android应用(I):简单介绍