參考:
http://gank.io/post/560e15be2dca930e00da1083
http://blog.csdn.net/lzyzsd/article/details/45033611
a library for composing asynchronous and event-based programs using observable sequences for the Java VM
Observables(被觀察者,事件源)和Subscribers(觀察者、訂閱)(Observer和Subscriber具有相同的角色得滤,而且Observer在subscribe()過程中最終會被轉(zhuǎn)換成Subscriber對象)
myObservable.subscribe(mySubscriber);
1.Observable和Subscriber可以做任何事情
Observable可以是一個數(shù)據(jù)庫查詢,Subscriber用來顯示查詢結(jié)果泼差;Observable可以是屏幕上的點擊事件,Subscriber用來響應(yīng)點擊事件;Observable可以是一個網(wǎng)絡(luò)請求行您,Subscriber用來顯示請求結(jié)果轴咱。
2.Observable和Subscriber是獨立于中間的變換過程的汛蝙。
在Observable和Subscriber中間可以增減任何數(shù)量的map。整個系統(tǒng)是高度可組合的朴肺,操作數(shù)據(jù)是一個很簡單的過程患雇。
我們可以將任意多個API調(diào)用鏈接起來。大家應(yīng)該都應(yīng)該知道同步所有的API調(diào)用宇挫,然后將所有API調(diào)用的回調(diào)結(jié)果組合成需要展示的數(shù)據(jù)是一件多么蛋疼的事情苛吱。這里我們成功的避免了callback hell(多層嵌套的回調(diào),導(dǎo)致代碼難以閱讀維護)∑鞅瘢現(xiàn)在所有的邏輯都包裝成了這種簡單的響應(yīng)式調(diào)用翠储。
操作符功能強大,操作符可以讓你對數(shù)據(jù)流做任何操作橡疼。將一系列的操作符鏈接起來就可以完成復(fù)雜的邏輯援所。代碼被分解成一系列可以組合的片段。這就是響應(yīng)式函數(shù)編程的魅力欣除。用的越多住拭,就會越多的改變你的編程思維。
In RxJava, you can tell yourObservercode which thread to run on usingsubscribeOn(), and which thread yourSubscribershould run on usingobserveOn()
subscribeOn(): 指定subscribe()所發(fā)生的線程历帚,即Observable.OnSubscribe被激活時所處的線程滔岳。或者叫做事件產(chǎn)生的線程挽牢。 *observeOn(): 指定Subscriber所運行在的線程谱煤。或者叫做事件消費的線程禽拔。
只要有異常發(fā)生onError()一定會被調(diào)用
使用RxJava刘离,Observable對象根本不需要知道如何處理錯誤!操作符也不需要處理錯誤狀態(tài)-一旦發(fā)生錯誤睹栖,就會跳過當(dāng)前和后續(xù)的操作符硫惕。所有的錯誤處理都交給訂閱者來做。
常見使用場景:
? ? ? ? ? ? ? ? ? 檢查緩存再網(wǎng)絡(luò)野来;
? ? ? ? ? ? ? ? ? 多個接口并發(fā)結(jié)束后更新數(shù)據(jù)恼除;
? ? ? ? ? ? ? ? ? 一個接口的請求依賴另一個API請求返回的數(shù)據(jù);
? ? ? ? ? ? ? ? ? 響應(yīng)式的界面梁只;
? ? ? ? ? ? ? ? ? RxJava 提供了對事件序列進行變換的支持缚柳,這是它的核心功能之一埃脏,也是大多數(shù)人說『RxJava 真是太好用了』的最大原因。所謂變換秋忙,就是將事件序列中的對象或整個序列進行加工處理彩掐,轉(zhuǎn)換成不同的事件或事件序列
使用響應(yīng)式編程可以更好的處理內(nèi)存泄露問題, 代碼也更加優(yōu)雅和可讀, 選擇執(zhí)行線程和監(jiān)聽線程也更加方便
RxAndroid
https://github.com/lzyzsd/Awesome-RxJava
隨著程序邏輯變得越來越復(fù)雜,它依然能夠保持簡潔(luojijianjie
RxAndroid是RxJava的一個針對Android平臺的擴展灰追。它包含了一些能夠簡化Android開發(fā)的工具
AndroidSchedulers提供了針對Android的線程系統(tǒng)的調(diào)度器堵幽;AndroidObservable,它提供了跟多的功能來配合Android的生命周期弹澎。bindActivity()和 bindFragment()方法默認(rèn)使用AndroidSchedulers.mainThread()來執(zhí)行觀察者代碼朴下,這兩個方法會在 Activity或者Fragment結(jié)束的時候通知被觀察者停止發(fā)出新的消息;
最后要介紹的是ViewObservable,使用它可以給View添加了一些綁定苦蒿。如果你想在每次點擊view的時候都收到一個事件殴胧,可以使用 ViewObservable.clicks(),或者你想監(jiān)聽TextView的內(nèi)容變化佩迟,可以使用ViewObservable.text()团滥。
ViewObservable.clicks(mCardNameEditText,false)
.subscribe(view?->?handleClick(view));
Retrofit(解耦)
http://www.tuicool.com/articles/26jUZjv
http://www.reibang.com/p/fb8d21978e38
Retrofit是一套RESTful架構(gòu)的Android(Java)客戶端實現(xiàn),基于注解报强,提供JSON to POJO(Plain Ordinary Java Object,簡單Java對象)灸姊,POJO to JSON,網(wǎng)絡(luò)請求(POST秉溉,GET,PUT力惯,DELETE等)封裝
Web 應(yīng)用程序最重要的 REST 原則是,客戶端和服務(wù)器之間的交互在請求之間是無狀態(tài)的.REST 指的是一組架構(gòu)約束條件和原則召嘶。滿足這些約束條件和原則的應(yīng)用程序或設(shè)計就是 RESTful父晶。從客戶端到服務(wù)器的每個請求都必須包含理解請求所必需的信息。如果服務(wù)器在請求之間的任何時間點重啟苍蔬,客戶端不會得到通知诱建。此外,無狀態(tài)請求可以由任何可用服務(wù)器回答碟绑,這十分適合云計算之類的環(huán)境【ソ常客戶端可以緩存數(shù)據(jù)以改進性能格仲。
另一個重要的 REST 原則是分層系統(tǒng),這表示組件無法了解它與之交互的中間層以外的組件诵冒。通過將系統(tǒng)知識限制在單個層凯肋,可以限制整個系統(tǒng)的復(fù)雜性,促進了底層的獨立性汽馋。
當(dāng) REST 架構(gòu)的約束條件作為一個整體應(yīng)用時侮东,將生成一個可以擴展到大量客戶端的應(yīng)用程序圈盔。它還降低了客戶端和服務(wù)器之間的交互延遲。統(tǒng)一界面簡化了整個系統(tǒng)架構(gòu)悄雅,改進了子系統(tǒng)之間交互的可見性驱敲。REST 簡化了客戶端和服務(wù)器的實現(xiàn)。
Retrofit的使用就是以下幾步:
? ? ? ? ? ?1.定義接口宽闲,參數(shù)聲明众眨,Url都通過Annotation指定
? ? ? ? ? ?2.通過RestAdapter生成一個接口的實現(xiàn)類(動態(tài)代理)
? ? ? ? ? ?3.調(diào)用接口請求數(shù)據(jù)
1 通過門面Retrofit來build一個Service Interface的proxy 通過create方法拿到接口的實現(xiàn)類,這里利用Java的Proxy類完成動態(tài)代理的相關(guān)代理
retrofit03.png
當(dāng)你調(diào)用這個Service Interface中的某個請求方法容诬,會被proxy攔截娩梨。
retrofit02.png
通過ServiceMethod來解析invoke的那個方法? ? ,通過解析注解览徒,傳參狈定,將它們封裝成我們所熟悉的request。然后通過具體的返回值類型习蓬,讓之前配置的工廠生成具體的CallAdapter纽什,ResponseConverter,這倆我們稍后再解釋友雳。
new一個OkHttpCall稿湿,這個OkHttpCall算是OkHttp的包裝類,用它跟OkHttp對接押赊,所有OkHttp需要的參數(shù)都可以看這個類饺藤。當(dāng)然也還是可以擴展一個新的Call的,比如HttpUrlConnectionCall流礁。但是有點耦合涕俗。看下圖標(biāo)注:
retrofit031.png
紅框中顯式的指明了OkHttpCall神帅,而不是通過工廠來生成Call再姑。所以如果你不想改源碼,重新編譯找御,那你就只能使用OkHttp了元镀。不過這不礙事。(可能也是因為還在持續(xù)更新中霎桅,所以這塊可能后面會改進的)
生成的CallAdapter有四個工廠栖疑,分別對應(yīng)不同的平臺,RxJava, Java8, Guava還有一個Retrofit默認(rèn)的滔驶。這個CallAdapter不太好用中文解釋遇革。簡單來說就是用來將Call轉(zhuǎn)成T的一個策略。因為這里具體請求是耗時操作,所以你需要CallAdapter去管理線程萝快。怎么管理锻霎,繼續(xù)往下看。
比如RxJava會根據(jù)調(diào)用方法的返回值揪漩,如Response<'T> |Result<'T>|Observable<'T> 旋恼,生成不同的CallAdapter。實際上就是對RxJava的回調(diào)方式做封裝氢拥。比如將response再拆解為success和error等蚌铜。(這塊還是需要在了解RxJava的基礎(chǔ)上去理解,以后有時間可以再詳細(xì)做分析)
在步驟5中嫩海,我們說CallAdapter還管理線程冬殃。比方說RxJava,我們知道叁怪,它最大的優(yōu)點可以指定方法在什么線程下執(zhí)行审葬。如圖
retrofit04.png
我們在子線程訂閱(subscribeOn),在主線程觀察(observeOn)奕谭。具體它是如何做的呢涣觉。我們看下源碼。
retrofit05.png
在adapt Call時血柳,subscribeOn了官册,所以就切換到子線程中了。
在adapt Call中难捌,具體的調(diào)用了Call execute()膝宁,execute()是同步的,enqueue()是異步的根吁。因為RxJava已經(jīng)切換了線程员淫,所以這里用同步方法execute()。
retrofit06.png
接下來的具體請求击敌,就是OkHttp的事情了介返,retrofit要做成的就是等待返回值。在步驟4中沃斤,我們說OkHttpCall是OkHttp的包裝類圣蝎,所以將OkHttp的response轉(zhuǎn)換成我們要的T,也是在OkHttpCall中執(zhí)行的衡瓶。
當(dāng)然具體的解析轉(zhuǎn)換操作也不是OkHttpCall來做的捅彻,因為它也不知道數(shù)據(jù)格式是什么樣的。所以它只是將response包裝成retrofit標(biāo)準(zhǔn)下的response鞍陨。
Converter->ResponseConverter,很明顯,它是數(shù)據(jù)轉(zhuǎn)換器诚撵。它將response轉(zhuǎn)換成我們具體想要的T缭裆。Retrofit提供了很多converter factory。比如Gson寿烟,Jackson澈驼,xml,protobuff等等筛武。你需要什么缝其,就配置什么工廠。在Service方法上聲明泛型具體類型就可以了徘六。
最后内边,通過聲明的observeOn線程回調(diào)給上層。這樣上層就拿到了最終結(jié)果待锈。至于結(jié)果再如何處理漠其,那就是上層的事了。
Retrofit與okhttp共同出自于Square公司竿音,retrofit就是對okhttp做了一層封裝和屎。把網(wǎng)絡(luò)請求都交給給了Okhttp
通過一系列的設(shè)計模式,封裝思想來解耦春瞬,看到現(xiàn)在柴信,其實retrofit就是一個負(fù)責(zé)調(diào)度的controller。先給retrofit配置好宽气,讓它能夠正常工作随常。你給它一個方法調(diào)用,它就在內(nèi)部開始運轉(zhuǎn)抹竹。這個方法以前我消化過嗎线罕,沒消化那就用一個ServiceMethod來解析它。解析后要用來配置一個request請求窃判。但它自己搞不定這事啊钞楼,所以需要給它一個轉(zhuǎn)接頭,通過轉(zhuǎn)接頭來使用okhttpcall袄琳。請求是做好了询件,但是response它又不認(rèn)識,
所以又請來convertor來幫忙唆樊,轉(zhuǎn)換完畢之后才吐出一個我們最終要的那個對象宛琅。