如何造個android Flow流式響應(yīng)的輪子
原因
在code代碼中,我們經(jīng)常碰到異步方法嵌套。比如提交文件之后在提交表單,提交數(shù)據(jù)根據(jù)是否成功然后做出其他邏輯處理。kotlin里面提出協(xié)程概念,利用語法糖來解決這個問題。在javaScript里面也有async/await來使異步用起來像同步。而在java中我暫時沒有找到該特性,使得寫起來異步嵌套感覺就是地獄,像吃了屎一樣。利用這春節(jié)幾天時間,嘗試著按自己思路去解決這個問題,造個流式的輪子,于是寫了Flow小框子。
想法
從生活中思考代碼,方法嵌套和水流的原理很相似,我們把每個異步當(dāng)成一個水管,水從一個個管道流過,每個管道可以對水進行加工轉(zhuǎn)換。轉(zhuǎn)換的這個過程我們當(dāng)成一個事件Event。在包裝事件中,我們可以對它進行線程轉(zhuǎn)換,事件轉(zhuǎn)換,合并拆分等一系列轉(zhuǎn)換。如果碰到異常,則直接終止這個流。
功能
簡單使用
通過Flow 靜態(tài)create方法創(chuàng)建一個流,then串聯(lián)下個流,如果不需要返回Void泛型。Event有兩個泛型P、R,第一個是前個流Flow的返回值類型,第二個是當(dāng)前流Flow返回類型。await exec方法是結(jié)束當(dāng)前事件流,并將結(jié)果代入下個流。
打印兩句話
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簡化之后
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é)果,每個flow后面使用resultThen都可以獲取流的結(jié)果。如果遇到異常,可以通過flow throwException方法拋出,可以在flow后面catchThen立刻處理,也可以在最后flow catchThen處理。finallyThen是事件流結(jié)束一個通知。
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傳遞一個Converter參數(shù),代表下個流切換。如果兩個Converter參數(shù),代表當(dāng)前流和下個流都切換線程。當(dāng)然你也可以實現(xiàn)Converter接口來實現(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)換成多個流
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();
多個流結(jié)果轉(zhuǎn)換成一個流
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();
生命周期解綁
通過flow watch方法。被觀察者必須實現(xiàn)ILifeObservable接口。
Flow.create((FirstEvent<Integer>) (flow, await) ->await.exec(0)) .watch(this).start();
總結(jié)
框子也里面提供了一些簡化的類,也可以和項目網(wǎng)絡(luò)請求框架抽象自己的Event,這樣和js的網(wǎng)絡(luò)的then就幾乎一樣了。后續(xù)根據(jù)實際需求再做調(diào)整,試驗中。
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
android 關(guān)于利用簽名的SHA1進行安全校驗的方法之一(推薦)
下面小編就為大家?guī)硪黄猘ndroid 關(guān)于利用簽名的SHA1進行安全校驗的方法之一(推薦)。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2017-01-01
Android ScrollView實現(xiàn)向上滑動控件頂部懸浮效果
這篇文章主要為大家詳細介紹了Android ScrollView實現(xiàn)向上滑動控件頂部懸浮效果,具有一定的參考價值,感興趣的小伙伴們可以參考一下2018-05-05
Android使用gallery和imageSwitch制作可左右循環(huán)滑動的圖片瀏覽器
本文主要介紹了android使用gallery和imageSwitch制作可左右循環(huán)滑動的圖片瀏覽器的示例代碼。具有很好的參考價值。下面跟著小編一起來看下吧2017-04-04

