这一系列的文章将会用来进行Coroutines和Rxjava在解决异步编程方面的对比。

案例一:为一个快速启动的App创建复杂的对象

如果希望自己的应用程序能够快速启动,那么处理创建对象的过程非常重要,如果对于复杂的对象创建发生在UI线程的话,将会引起丢帧的情况。

所以对于这种情况我们我们需要在后台线程中做这些操作。

RxJava

我们如何使用Rxjava来初始化我们想要的对象?

fun initializeObjectsAsync(): Completable{

return Completable.create{ emitter ->

try{

heavyInitialzation()

if(!emitter?.isDisposed){

emitter?.onComplete()

}

}catch(e:Exception){

if (!emitter?.isDisposed) {

emitter?.onError(e)

}

}

}

}

正如你所见,我们创建了一个方法返回Completable对象,在方法内部,我们通过Completable.create创建了一个Completable,他将使用一个发射器(这个对象是可以被订阅的)。

执行完复杂的初始化后,我们将通知成功,如果有错误发生,我们将通知所发生的错误,这是因为发射器的类型是CompletableEmitter,而onComplete和onError是可用于将结果传递给订阅服务器的方法。

另一种方法是使用Completable.fromCallable()

fun initializeObjectsAsync(): Completable {

return Completable.fromCallable({

heavyInitialization()

})

}

我们如何消费该方法呢?

Observables和Completables在Rxjava中都是冷冰冰的,这意味着我们只有订阅时,才会执行Completable.create中的代码,需要记住的是,每次订阅都会执行。

我们必须订阅我们在上面创建的initializeObjectsAsync函数中创建的Completable。

fun initializeObjects() {

initializeObjectsAsync()

.subscribeOn(Schedulers.computation())

.observeOn(AndroidSchedulers.mainThread())

.subscribe({

// The initialization succeeded!

// We can perform UI changes here

}, {

// An Error occurred!

})

}

我们如何告诉RxJava我们想要在后台线程中执行初始化操作?我们使用subscribeOn操作符来告诉RxJava,我们希望Completable.create中的代码能够在后台线程上执行。

当执行完毕时,我们需要对UI进行更新操作,我们可以使用observableOn操作符来告诉RxJava我们想在Android主线程中监听结果。

只有当你订阅Completable时,才会执行Completable.create中的代码

定义线程之后,我们需要启动订阅才能在完成时接收到通知,使用.subscribe方法来做到这一点,我们需要传递两个代码块,一个是接收成功的方法,一个是接收失败的方法。

如果想要上述代码被执行,我们需要创建一个Android Activity,例如,我们可以在onCreate方法中调用这个方法。

override fun onCreate(savedInstanceState: Bundle?) {

super.onCreate(savedInstanceState)

setContentView(R.layout.activity_main)

initializeObjects()

}

Kotlin Coroutines

使用Coroutines的话会更简单,从概念上讲,协程和线程类似,我们可以编写在特定线程上运行的代码。

CoroutineBuilder是一个可以用来创建Coroutine的方法,运行一段代码,并以某种形式访问其结果,CoroutineBuilder的例子有:launch,async,runBlocking...

假设我们要像在onCreate方法中那样调用heavyInitialization方法,我们可以使用CoroutineBuilder启动创建一个Coroutine,并在要运行的代码块执行大量初始化的代码。

fun initializeObjects() {

launch(CommonPool) {

heavyInitialization()

}

}

CommonPool类似于RxJava中的Schedulers.computation(),将会在后台线程中运行代码。

让我们模仿RxJava中构建的例子,我们想知道它什么时候完成初始化复杂对象和错误的处理。

fun initializeObjects() {

launch(CommonPool) {

try {

heavyInitialization()

// The initialization succeeded!

withContext(UI) {

// We can perform UI changes here

}

} catch (e: Exception) {

// An Error occurred!

}

}

}

由于Coroutine中的代码被顺序执行,因此在初始化成功代码将接着初始化的代码执行。

和以前一样,我们可以将调用封装在try catch块中进行错误处理。

我们如何切换UI线程来通知UI更新,这里有一个方法withContext,使用另一个CoroutineContext来运行其中的代码块。

我们在示例中看到的CoroutineContext不是标准Kotlin Coroutines库中的一部分,由于它是Android专用的,因此可以在其他库中使用:org.jetbrains.kotlinx:kotlinx-coroutines-android:$kotlin_coroutines_version

示例二:在后台线程执行斐波那契数列

区别于在后台执行一些操作,我们也需要返回一个值,现在我们在用户点击按钮是计算斐波那契数列。

想象一下我们使用下面的代码来计算斐波那契数列:

private fun fib(n: Long): Long {

return if (n <= 1) n

else fib(n - 1) + fib(n - 2)

}

我们如何在后台线程中计算他并且返回结果呢?

RxJava

这次我们使用Single来实现。

fun fibonacciAsync(number: Long): Single =

Single.create({ emitter ->

val result = fib(number)

if (!emitter?.isDisposed) {

emitter.onSuccess(result)

}

})

你也可以使用fromCallback方法:

fun fibonacciAsync(number: Long): Single =

Single.fromCallable({

return fib(number)

})

我们把我们想要的数字作为该函数的参数传递,这也将在Single.create代码块中使用,例如,我们可以从EditText中获取该号码。

@OnClick(R.id.my_button)

fun onButtonClicked() {

fibonacciAsync(numberInputEditText.text.toString().toLong())

.subscribeOn(Schedulers.computation())

.observeOn(AndroidSchedulers.mainThread())

.subscribe({ fibonacciNumber ->

//Update UI with the result

myTextView.text = fibonacciNumber

},{

// Error happened

})

}

用户每次点击按钮,我们都将计算一个新的斐波那契数值,如果用户修改了Edittext中的值,结果也将会变得不同。

Kotlin Coroutines

这个示例将会和上面的一样简单,当用户点击按钮,我们就开启一个Coroutine来计算斐波那契数列。

@OnClick(R.id.my_button)

fun onButtonClicked(){

launch(CommonPool) {

val result = fibonacciAsync (

numberInputEditText.text.toString().toLong()

)

withContext(UI){

fibonacciResultTextView.text = result

}

}

}

下篇文章将介绍取消执行。

如何取消Observable和Coroutine。不要错过。

java coroutine类_Coroutines和Rxjava异步编程对比相关推荐

  1. java futuretask 源码解析_Java异步编程——深入源码分析FutureTask

    Java的异步编程是一项非常常用的多线程技术. 之前通过源码详细分析了ThreadPoolExecutor<你真的懂ThreadPoolExecutor线程池技术吗?看了源码你会有全新的认识&g ...

  2. Java 8中的并行和异步编程

    并行代码是在多个线程上运行的代码,曾经是许多经验丰富的开发人员的噩梦,但是Java 8带来了许多更改,这些更改应该使这种提高性能的技巧更加易于管理. 并行流 在Java 8之前,并行(或并发)代码与顺 ...

  3. Java中如何使用非阻塞异步编程——CompletableFuture

    分享一波:程序员赚外快-必看的巅峰干货 对于Node开发者来说,非阻塞异步编程是他们引以为傲的地方.而在JDK8中,也引入了非阻塞异步编程的概念.所谓非阻塞异步编程,就是一种不需要等待返回结果的多线程 ...

  4. java 并发 异步_Java并发 CompletableFuture异步编程的实现

    前面我们不止一次提到,用多线程优化性能,其实不过就是将串行操作变成并行操作.如果仔细观察,你还会发现在串行转换成并行的过程中,一定会涉及到异步化,例如下面的示例代码,现在是串行的,为了提升性能,我们得 ...

  5. Java 异步编程 (5 种异步实现方式详解)

    同步操作如果遇到一个耗时的方法,需要阻塞等待,那么我们有没有办法解决呢?让它异步执行,下面我会详解异步及实现 @mikechen 目录 什么是异步? 一.线程异步 二.Future异步 三.Compl ...

  6. C#:异步编程和线程的使用(.NET 4.5 ),异步方法改为同步执行

    摘自:http://www.codeproject.com/Articles/996857/Asynchronous-programming-and-Threading-in-Csharp-N(葡萄城 ...

  7. [你必须知道的异步编程]——异步编程模型(APM)

    本专题概要: 引言 你知道APM吗? 你想知道如何使用异步编程模型编写代码吗? 使用委托也可以实现异步编程,你知道否? 小结 一.引言 在前面的C#基础知识系列中介绍了从C#1.0--C#4.0中一些 ...

  8. C# 线程知识--异步编程模型(APM)

    在构建高性能.可伸缩的应用程序时,必定会采用异步操作来提升应用程序性能,改善用户体验,异步操作与线程池结合允许使用很少的线程执行许多的操作.CLR中提供了一种异步操作的模式即异步编程模式. 1.异步编 ...

  9. 在Java中异步编程,同事非要用rxJava,被我一顿吐槽!

    在Java中异步编程,不一定非要使用rxJava, Java本身的库中的CompletableFuture可以很好的应对大部分的场景. 这篇文章介绍 Java 8 的 CompletionStage ...

最新文章

  1. Docker运行PostgreSQL
  2. C++ STL 之 unordered_set 使用(包括unordersd_map)
  3. .NET开发框架(四)-服务器IIS实践教程
  4. 学校计算机数据采集处理系统,中学化学计算机数据采集处理系统实验室装备
  5. OpenMV(五)--STM32实现人脸识别
  6. Linux运维面试题之--网页打开缓慢如何优化
  7. Java swing实现简单的浏览器源码免费分享
  8. Cannot set property 'onclick' of null报错
  9. NLP—6.数据不平衡处理
  10. 磁盘驱动器号的修改恢复
  11. python好玩的代码-我珍藏的一些好的Python代码,技巧
  12. 互联网寒冬:轮回之下,几人破茧,几人沉沦
  13. java功能模块_系统功能模块详解 java应该学习什么?
  14. 基于AT89C51单片机的超声波传感器测距【程序详细代码及注释】
  15. Echarts柱状图和折线图结合
  16. 高通apq8074修改DDR频率
  17. MySQL备库复制延迟的原因及解决办法
  18. docker教程-docker镜像
  19. linux服务器防病毒,Linux服务器防病毒实战(3)
  20. MySQL-存储过程与函数(PRECEDURE/FUNCTION/DECLARE/SET/CALL/DELIMITER)

热门文章

  1. 编译Android源码相关资源及文章
  2. .Net框架集WebClient类向WinCE平台上传文件(FTP方式)延迟15秒释疑
  3. aspnet 后台调用前台js函数
  4. ListView原理
  5. 读《大道至简》第二章有感
  6. POJ 1236 Network of Schools(强连通 Tarjan+缩点)
  7. 网盘中搭建git服务
  8. XL, an extensible programming language, implements concept programming
  9. MFC初探 —— 捕获键盘消息
  10. 闲来无事,仿了一个百度杀毒主界面