Android开发中的Kotlin Coroutine VS RxJava

前言

首先,我是个Kotlin的重度使用者。我用Kotlin写事后台应用,写过前端,写过近10个Android项目。前端

我我的以为,Kotlin充满了现代化的软件开发所需的语言特点,在我用过的全部语言中(ES6,Python,Go,Java)是最舒服最天然的;JetBrain作了多年IDE,最懂开发者的尿性。若是你会Java,几乎没有学习成本。除了其余优秀的语法外,我也格外喜欢Coroutine,下面就来吹一波。git

先吹一波

Coroutine,也叫协程,或者微线程(或者随便你怎么叫它);它是可暂停可恢复的比线程更小的任务单元。目前我所用到的支持协程序的语言有NodeJS,Go,Python;Java并不支持。从原理上看,它们的核心实现原理大都是OS Thread Pool + 状态机,就是靠系统线程池来调度,靠状态机来控制状态。只不过有些是语言自然就支持的,好比Go;而Kotlin是用编译技术来实现的。github

无论如何实现,它们通常有这样2个好处:网络

  1. 更低资源消耗和更好的调度性能
  2. 异步代码变同步

至于第一点在Web应用上很实用,由于Web大可能是IO密集,它在低配置的机器上能够带来更高的并发,资源消耗还少。可是在Andorid上然并卵,就算是多线程下载的场景,通常并发任务也就5个左右,根本体现不出它的做用。多线程

第二点在Android上就很实用了,咱们常常会遇到先执行一段耗时操做,在执行一段后续逻辑的场景。否则Andorid也不会搞出AsyncTask,IntentService,HandlerThread了。它能够彻底消除咱们的callback。并发

场景

先看一个真实的发布动态场景。动态中包含文字,用户拍摄或选择的9张图片。整个动态的发布流程是这样:异步

  1. 先异步对9张图片进行压缩
  2. 而后异步将9张图片上传到Server,拿到9个图片Id
  3. 将文字和图片Id一块上传

第1步,第2步和第3步自己都是须要异步,但1,2,3步之间又是同步顺序执行的关系。post

Java中能够用FutureTask实现。性能

用RxJava来作大概是大量的Callback流配合map操做符来完成,代码虽然比FetureTask好不少,可是并不美观。学习

用Kotlin Coroutine来作就是:

GlobalScope.launch {
    // 其余参数
    val params = hashMapOf(
            "content" to content,
            "longitude" to longitude,
            "latitude" to latitude,
            "title" to title
    )
    
    //1. 构建压缩图片的task
    val compressedTasks = paths.map { compressImage(it) } // paths是用户的图片地址集合
    //2. 构建上传图片的task,上传任务就是http请求
    val uploadTasks = compressedTasks.map { uploadImage(it.await()) } //压缩任务并发执行
    //3. 执行上传图片task拿到结果
    val imageIds = uploadTasks.map { it.await()!!.data.id } // 上传图片任务并发执行
    params["images"] = imageIds.toJson()

    val result = "$BASEURL/weibo/create".http(this)
            .headers(...)
            .params(params)
            .post<HttpResult<Dynamic>>().await()
            
    // 更新LiveData 
    weiboCreateData.postValue(result)
}
复制代码

几个构建task的代码在这里:

/** * 构建压缩任务 */
fun compressImage(path: String): Deferred<File>{
    val deferred = CompletableDeferred<File>()
    // 这里是使用Luban库来压缩图片,具体逻辑能够忽略
    deferred.complete(Luban.with(App.context)
            .load(path)
            .ignoreBy(100)
            .get()[0])
    return deferred
}

/** * 构建上传图片的任务 */
fun uploadImage(file: File): Deferred<HttpResult<List<UploadData>>?> {
    return "$BASEURL/weibo/upload".http(this)
            .headers(createCommonHeaders(null))
            .params("file" to file)
            .post<HttpResult<List<UploadData>>>()
}
复制代码

能够看到这种复杂逻辑下,所有代码也就30行左右,而且没有一个Callback,是否是比RxJava好。

上面的网络请求是来自于个人一个库:github.com/li-xiaojun/…

异步逻辑以后通知UI,我建议用LiveData,省去不少界面销毁的判断,并且监听能够自动解除注册,RxJava还要手动dispose。

若是你就想在UI中执行一段异步逻辑而后回到UI线程更新UI,那能够用anko库的封装。

最后

其实,我并不用RxJava,从看到大量的Callback时就放弃了。

我对RxJava并无深刻了解,对于上面的场景,若是RxJava能作的更好,烦请指出。

相关文章
相关标签/搜索