首先,我是个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个好处:网络
至于第一点在Web应用上很实用,由于Web大可能是IO密集,它在低配置的机器上能够带来更高的并发,资源消耗还少。可是在Andorid上然并卵,就算是多线程下载的场景,通常并发任务也就5个左右,根本体现不出它的做用。多线程
第二点在Android上就很实用了,咱们常常会遇到先执行一段耗时操做,在执行一段后续逻辑的场景。否则Andorid也不会搞出AsyncTask,IntentService,HandlerThread了。它能够彻底消除咱们的callback。并发
先看一个真实的发布动态场景。动态中包含文字,用户拍摄或选择的9张图片。整个动态的发布流程是这样:异步
第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能作的更好,烦请指出。