如何造個(gè)android Flow流式響應(yīng)的輪子
原因
在code代碼中,我們經(jīng)常碰到異步方法嵌套。比如提交文件之后在提交表單,提交數(shù)據(jù)根據(jù)是否成功然后做出其他邏輯處理。kotlin里面提出協(xié)程概念,利用語(yǔ)法糖來(lái)解決這個(gè)問(wèn)題。在javaScript里面也有async/await來(lái)使異步用起來(lái)像同步。而在java中我暫時(shí)沒(méi)有找到該特性,使得寫(xiě)起來(lái)異步嵌套感覺(jué)就是地獄,像吃了屎一樣。利用這春節(jié)幾天時(shí)間,嘗試著按自己思路去解決這個(gè)問(wèn)題,造個(gè)流式的輪子,于是寫(xiě)了Flow小框子。
想法
從生活中思考代碼,方法嵌套和水流的原理很相似,我們把每個(gè)異步當(dāng)成一個(gè)水管,水從一個(gè)個(gè)管道流過(guò),每個(gè)管道可以對(duì)水進(jìn)行加工轉(zhuǎn)換。轉(zhuǎn)換的這個(gè)過(guò)程我們當(dāng)成一個(gè)事件Event。在包裝事件中,我們可以對(duì)它進(jìn)行線程轉(zhuǎn)換,事件轉(zhuǎn)換,合并拆分等一系列轉(zhuǎn)換。如果碰到異常,則直接終止這個(gè)流。
功能
簡(jiǎn)單使用
通過(guò)Flow 靜態(tài)create方法創(chuàng)建一個(gè)流,then串聯(lián)下個(gè)流,如果不需要返回Void泛型。Event有兩個(gè)泛型P、R,第一個(gè)是前個(gè)流Flow的返回值類型,第二個(gè)是當(dāng)前流Flow返回類型。await exec方法是結(jié)束當(dāng)前事件流,并將結(jié)果代入下個(gè)流。
打印兩句話
Flow.create(new Event<Void,Void>() {
@Override
public void run(Flow flow, Void aVoid, Await<Void> await) {
System.out.println("this is first flow");
await.exec(null);
}
}).then(new Event<Void, Void>() {
@Override
public void run(Flow flow, Void aVoid, Await<Void> await) {
System.out.println("this is two flow");
await.exec(null);
}
}).start();
Lambda簡(jiǎn)化之后
Flow.create((NoneEvent) (flow, await) -> {
System.out.println("this is first flow");
await.exec();
}).then((NoneEvent) (flow, await) -> {
System.out.println("this is two flow");
await.exec();
}).start();
兩數(shù)相加
Flow.create((FirstEvent<Integer>) (flow, await) ->
await.exec(3))
.then((Event<Integer, Integer>) (flow, integer, await) ->
await.exec(integer + 5))
.resultThen((flow, result) ->
System.out.println("total is"+result))
.start();
resultThen方法返回是當(dāng)前流的結(jié)果,每個(gè)flow后面使用resultThen都可以獲取流的結(jié)果。如果遇到異常,可以通過(guò)flow throwException方法拋出,可以在flow后面catchThen立刻處理,也可以在最后flow catchThen處理。finallyThen是事件流結(jié)束一個(gè)通知。
Flow.create((FirstEvent<Integer>) (flow, await) ->
await.exec(0))
.then((Event<Integer, Integer>) (flow, perVal, await) ->{
if(perVal == 0){
flow.throwException("Dividend cannot be 0!");
}else{
await.exec(perVal/5);
}
})
.resultThen((flow, result) ->
System.out.println("total is"+result))
.catchThen((flow, e) ->
System.out.println(e.getMessage()))
.finallyThen((flow, await) ->
System.out.println("this is flow end")).start();
切換線程
使用flow on方法可以切換線程,on傳遞一個(gè)Converter參數(shù),代表下個(gè)流切換。如果兩個(gè)Converter參數(shù),代表當(dāng)前流和下個(gè)流都切換線程。當(dāng)然你也可以實(shí)現(xiàn)Converter接口來(lái)實(shí)現(xiàn)其他功能。
Flow.create((FirstEvent<Integer>) (flow, await) ->
await.exec(0))
.on(AndroidMain.get(),SingleThread.get())
.then((Event<Integer, Integer>) (flow, perVal, await) ->{
if(perVal == 0){
flow.throwException("Dividend cannot be 0!");
}else{
await.exec(perVal/5);
}
})
.on(AndroidMain.get())
.resultThen((flow, result) ->
System.out.println("total is"+result))
.on(AndroidMain.get())
.catchThen((flow, e) ->
System.out.println(e.getMessage()))
.on(SingleThread.get())
.finallyThen((flow, await) ->
System.out.println("this is flow end")).start();
Collection結(jié)果轉(zhuǎn)換成多個(gè)流
Flow.each((FirstEvent<List<String>>) (flow, await) -> {
ArrayList<String> list = new ArrayList<>();
list.add("1");
list.add("2");
list.add("3");
await.exec(list);
}).then((LastEvent<String>) (flow, s, await) -> {
System.out.println("this is"+s);
}).start();
多個(gè)流結(jié)果轉(zhuǎn)換成一個(gè)流
Flow.merge((flow, await) -> await.exec(1),
(flow, await) -> await.exec(2),
(flow, await) -> await.exec(2)).resultThen((flow, result)
-> System.out.println"result"+result)).start();
條件選擇
根據(jù)條件判斷重新發(fā)起Flow流(返回參數(shù)可以不一樣)
Flow.create((NoneEvent) (flow,await) ->{
System.out.println("start");
await.exec();
})
.on(SingleThread.get())
.conditionThen((VoidCondition) () -> false,
Flow.create((NoneEvent) (flow,await) -> {
System.out.println("this is true");
await.exec();
}),
Flow.create((NoneEvent) (flow,await) -> {
System.out.println("this is false");
await.exec();
})).start();
根據(jù)條件判斷執(zhí)行Flow流,可以合并到一起。(返回參數(shù)必須一致)
Flow.condition2(() -> isGo, (FirstEvent<Integer>) (flow, await) -> {
System.out.println("this is true");
await.exec(1);
}, (flow, await) -> {
System.out.println("this is false");
await.exec(0);
}).resultThen((flow, result) -> System.out.println("result"+result))
.watch(this).start();
生命周期解綁
通過(guò)flow watch方法。被觀察者必須實(shí)現(xiàn)ILifeObservable接口。
Flow.create((FirstEvent<Integer>) (flow, await) ->await.exec(0)) .watch(this).start();
總結(jié)
框子也里面提供了一些簡(jiǎn)化的類,也可以和項(xiàng)目網(wǎng)絡(luò)請(qǐng)求框架抽象自己的Event,這樣和js的網(wǎng)絡(luò)的then就幾乎一樣了。后續(xù)根據(jù)實(shí)際需求再做調(diào)整,試驗(yàn)中。
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
Android利用GridView實(shí)現(xiàn)單選效果
本篇文章主要介紹了Android利用GridView實(shí)現(xiàn)單選效果的相關(guān)知識(shí),具有很好的參考價(jià)值。下面跟著小編一起來(lái)看下吧2017-05-05
Android仿微信列表滑動(dòng)刪除之可滑動(dòng)控件(一)
這篇文章主要為大家詳細(xì)介紹了Android仿微信列表滑動(dòng)刪除之可滑動(dòng)控件,具有一定的實(shí)用性和參考價(jià)值,感興趣的小伙伴們可以參考一下2016-08-08
android 關(guān)于利用簽名的SHA1進(jìn)行安全校驗(yàn)的方法之一(推薦)
下面小編就為大家?guī)?lái)一篇android 關(guān)于利用簽名的SHA1進(jìn)行安全校驗(yàn)的方法之一(推薦)。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-01-01
Android ScrollView實(shí)現(xiàn)向上滑動(dòng)控件頂部懸浮效果
這篇文章主要為大家詳細(xì)介紹了Android ScrollView實(shí)現(xiàn)向上滑動(dòng)控件頂部懸浮效果,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-05-05
Android使用gallery和imageSwitch制作可左右循環(huán)滑動(dòng)的圖片瀏覽器
本文主要介紹了android使用gallery和imageSwitch制作可左右循環(huán)滑動(dòng)的圖片瀏覽器的示例代碼。具有很好的參考價(jià)值。下面跟著小編一起來(lái)看下吧2017-04-04
android使用Rxjava實(shí)現(xiàn)倒計(jì)時(shí)功能
這篇文章主要為大家詳細(xì)介紹了android使用Rxjava實(shí)現(xiàn)倒計(jì)時(shí)功能,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-06-06
Android自定義webView頭部進(jìn)度加載效果
這篇文章主要介紹了Android自定義webView頭部進(jìn)度加載效果,小編畫(huà)一條進(jìn)度線,然后加載webview上面,具體實(shí)現(xiàn)代碼大家參考下本文2017-11-11

