首先,我是個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能作的更好,煩請指出。