Android结合kotlin使用coroutine的方法实例

最近入了Android坑,目前还处于疯狂学习的状态,所以很久都没有写博客了。今天记录一个小代码片段,在Android上使用coroutine 的小例子。

由于我自己是做一个记账软件来学习的,我用了gRPC,最开始我是使用线程来做网络请求的:

thread {
 // 网络请求代码

 runOnUiThread {
  // 更新UI的代码
 }
}

今天把这一套全部重写成用coroutine。

首先coroutine得有个调度器,英文叫做 “Dispatchers”,有这么几个:

  • Dispatchers.Main 这里面的coroutine跑在主线程上,在Android里也就是UI线程,所以如果在这里面的coroutine也执行大量耗时代码的话,也是会卡UI的
  • Dispatchers.IO 用来跑大IO的
  • Dispatchers.Default 用来跑高CPU消耗的
  • Dispatchers.Unconfined 不绑定在任何特定执行线程上

然后,为了多个coroutine之间可以分组啊,就像进程里可以放很多线程那样,又搞了一个概念,叫做 scope,默认有一个全局scope,叫做 GlobalScope,全局的, 就和全局变量一样,在Android上,这个里面跑的coroutine,生命周期和app一样久,不推荐在这里起coroutine。

推荐的方式是每个Activity里起一个scope,然后再launch。

所以我就这样写基类:

abstract class BaseActivity : AppCompatActivity(), CoroutineScope {
 /*
 默认的coroutine scope是Main,也就是UI线程(主线程)。如果要做IO,比如网络请求,记得
 包裹在 launch(Dispatchers.IO) {} 里,如果要大量计算,包裹在 launch(Dispatcher.Default) {} 里
 或者直接写 launch。 UI操作则用 withContext(Dispatchers.Main) {} 切回来
  */
 private val job = SupervisorJob()
 override val coroutineContext: CoroutineContext
  get() = Dispatchers.Main + job

 override fun onDestroy() {
  super.onDestroy()
  coroutineContext.cancelChildren()
 }

这样子之后,就可以直接launch,起coroutine了:

launch {
 val req = CreateFeedbackReq.newBuilder().build()
 val respAny = callRPC {
  api.createFeedback(req)
 }
 respAny?:return@launch

 val resp = respAny as CreateFeedbackResp
 if (handleRespAction(resp.action)) {
  withContext(Dispatchers.Main) {
   showSnackBar(R.string.thank_you_for_feedback)
   delay(1000)
   finish()
  }
 }
}

如上,默认情况下,root coroutine就是当前所在activity,而他们默认会在 Dispatchers.Main 上执行,如果想要coroutine在 别的 dispatcher 上执行,就用 withContext,然后里面如果又想更新UI的话,就用 withContext(Dispatchers.Main)。

那为啥 launch 不传参数的话,就是直接用的 Dispatchers.Main 呢?因为其实 CoroutineScope 是一个接口,而 coroutineContext 是里面的一个变量:

public interface CoroutineScope {
 /**
  * The context of this scope.
  * Context is encapsulated by the scope and used for implementation of coroutine builders that are extensions on the scope.
  * Accessing this property in general code is not recommended for any purposes except accessing the [Job] instance for advanced usages.
  *
  * By convention, should contain an instance of a [job][Job] to enforce structured concurrency.
  */
 public val coroutineContext: CoroutineContext
}

我们再来看看 launch 的实现:

public fun CoroutineScope.launch(
 context: CoroutineContext = EmptyCoroutineContext,
 start: CoroutineStart = CoroutineStart.DEFAULT,
 block: suspend CoroutineScope.() -> Unit
): Job {
 val newContext = newCoroutineContext(context)
 val coroutine = if (start.isLazy)
  LazyStandaloneCoroutine(newContext, block) else
  StandaloneCoroutine(newContext, active = true)
 coroutine.start(start, coroutine, block)
 return coroutine
}

@ExperimentalCoroutinesApi
public actual fun CoroutineScope.newCoroutineContext(context: CoroutineContext): CoroutineContext {
 val combined = coroutineContext + context
 val debug = if (DEBUG) combined + CoroutineId(COROUTINE_ID.incrementAndGet()) else combined
 return if (combined !== Dispatchers.Default && combined[ContinuationInterceptor] == null)
  debug + Dispatchers.Default else debug
}

可以看到,默认情况下,会把当前的 coroutineContext 放在前面。

Kotlin的coroutine很好用,不过我感觉还是有点复杂,我也还在学习。

ref:

https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines/-dispatchers/index.html

到此这篇关于Android结合kotlin使用coroutine的文章就介绍到这了,更多相关Android结合kotlin使用coroutine内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • Kotlin Coroutines执行异步加载示例详解

    前言 Kotlin Coroutines是Kotlin推出的新的异步API.并不是解决所有问题的最优方案,但是希望在许多情况下它会使事情变得更容易一些.这里只简单的展示一下这个库在安卓中的具体使用方案.下面话不多说了,来一起看看详细的介绍吧. 引入Coroutines //在application的build.gradle文件中的android节点添加如下的代码 kotlin { experimental { coroutines 'enable' } } //添加下面两行到依赖中 implem

  • Kotlin学习教程之协程Coroutine

    定义 Coroutine翻译为协程,Google翻译为协同程序,一般也称为轻量级线程,但需要注意的是线程是操作系统里的定义概念,而协程是程序语言实现的一套异步处理的方法. 在Kotlin文档中,Coroutine定义为一个可被挂起的计算实例,下面话不多说了,来一起看看详细的介绍吧. 配置 build.gradle中dependencies 添加下面2行,注意coroutine目前仍处于experiment阶段,但Kotline官方保证向前兼容. dependencies { implementa

  • Android结合kotlin使用coroutine的方法实例

    最近入了Android坑,目前还处于疯狂学习的状态,所以很久都没有写博客了.今天记录一个小代码片段,在Android上使用coroutine 的小例子. 由于我自己是做一个记账软件来学习的,我用了gRPC,最开始我是使用线程来做网络请求的: thread { // 网络请求代码 runOnUiThread { // 更新UI的代码 } } 今天把这一套全部重写成用coroutine. 首先coroutine得有个调度器,英文叫做 "Dispatchers",有这么几个: Dispatc

  • Android 中隐藏虚拟按键的方法实例代码

    下面通过一段代码给大家讲解android 隐藏虚拟按键的方法,废话不多说了,大家多多看看代码和注释吧,具体代码如下所示: /** * 隐藏虚拟按键,并且全屏 */ protected void hideBottomUIMenu() { //隐藏虚拟按键,并且全屏 if (Build.VERSION.SDK_INT > 11 && Build.VERSION.SDK_INT < 19) { // lower api View v = this.getWindow().getDec

  • Android实现定时器的五种方法实例详解

    一.Timer Timer是Android直接启动定时器的类,TimerTask是一个子线程,方便处理一些比较复杂耗时的功能逻辑,经常与handler结合使用. 跟handler自身实现的定时器相比,Timer可以做一些复杂的处理,例如,需要对有大量对象的list进行排序,在TimerTask中执行不会阻塞子线程,常常与handler结合使用,在处理完复杂耗时的操作后,通过handler来更新UI界面. timer.schedule(task, delay,period); task: Time

  • Android开发实现拍照功能的方法实例解析

    本文实例讲述了Android开发实现拍照功能的方法.分享给大家供大家参考,具体如下: 解析: 1)判断是否有摄像头checkCameraHardware(this) 2)获得相机camera = Camera.open(0); 3)把相机添加到mPreView = new SurfacePreView(this, mCamera); 4)实现拍照 mCamera.autoFocus 5)在拍照后使用mCamera.takePicture(null, null, mPicture);方法把图片保存

  • Android编程设置全屏的方法实例详解

    本文实例讲述了Android编程设置全屏的方法.分享给大家供大家参考,具体如下: 在实际的应用程序开发中,我们有时需要把 Activity 设置成全屏显示,一般情况下,可以通过两种方式来设置全屏显示效果.其一,通过在代码中可以设置,其二,通过manifest配置文件来设置全屏. 其一:在代码中设置(如下) package xiaohang.zhimeng; import android.app.Activity; import android.content.pm.ActivityInfo; i

  • Android中常用的XML生成方法实例分析

    本文实例讲述了Android中常用的XML生成方法.分享给大家供大家参考.具体如下: 1. java代码: package com.android.antking.xml; import java.io.OutputStream; import java.util.List; import org.xmlpull.v1.XmlSerializer; import android.util.Xml; /**采用pull 生成xml文件 * * @author antkingwei * */ pub

  • Android编程之菜单的实现方法实例详解

    本文实例讲述了Android编程之菜单的实现方法.分享给大家供大家参考,具体如下: Options Menu 当用户按下menu button按钮时显示的菜单 Context Menu 当用户长久按住屏幕,被注册显示上下文菜单的视图时显示的菜单 Submenu    当用户按下一个菜单的某个选项时弹出的子菜单 以上三种菜单也就是我们经常所说的:选项菜单,上下文菜单和子菜单. 一.上下文菜单 1. 实现onCreateContextMenu即可创建该菜单 @Override public void

  • Android实现悬浮窗的简单方法实例

    目录 1. 前言 2.原理 3.具体实现 3.1浮窗布局 3.2 悬浮窗的实现 1. 使用服务Service 2. 获取WindowManager并设置LayoutParams 3. 创建View并添加到WindowManager 4. 实现悬浮窗的拖拽和关闭功能 5. 利用广播进行通信 6. 设置权限 3.3 完整代码 4. 总结 1. 前言 现在很多应用都有小悬浮窗的功能,比如看直播的时候,通过Home键返回桌面,直播的小窗口仍可以在屏幕上显示.下面将介绍下悬浮窗的的一种简单实现方式. 2.

  • Android 使用Kotlin自定义View的方法教程

    前言 随着google宣布kotlin作为官方开发语言,在Android中使用kotlin的趋势也越来越明显,最近被kotlin的文章轰炸了,所以决定上手试一下,试过之后,感觉靠它灵简直有魔性.特别是一句话写出一个复杂的循环的时候,简直被惊呆.而且使用AS,Java代码可以直接转成Kotlin. 效果图如下: 首先是这次自定义View的效果图,是一张饼图.如果是用java写的话也就几十行,觉得换成Kotlin的话可能会更少. 示例代码 主要的功能是可以任设定数据的个数,我这里是4个数据,可以任意

  • android图片压缩的3种方法实例

    android 图片压缩方法: 第一:质量压缩法: 复制代码 代码如下: private Bitmap compressImage(Bitmap image) { ByteArrayOutputStream baos = new ByteArrayOutputStream();        image.compress(Bitmap.CompressFormat.JPEG, 100, baos);//质量压缩方法,这里100表示不压缩,把压缩后的数据存放到baos中        int op

随机推荐