前幾天健哥喊我研究一下RvJava,在網絡請求用,更簡潔更有條理,而後就會抽空研究研究,如今項目裏網絡庫是Volley,就結合項目和網上的demo看,忽然腦殼蹦出這個問題,如今看起來這個問題有一點蠢蠢的。git
firstly,名詞解釋一下。github
Volley是谷歌爸爸給我們封裝好了的網絡請求庫,幫咱們封裝了具體的請求,線程切換以及數據轉換,適合短小多併發的網絡請求。網絡
Volley要主要用到的兩個類:RequestQueue和Request。併發
兩個最基礎的Request實現JsonObjectRequest和StringRequest,都是請求的做用,用以請求的「信物「」不一樣而已,全部的HTTP請求都是由這個類建立的,它封裝了用於HTTP請求的主要參數。(這是異步網絡請求,因此有Response Listener,Error Listener的回調)app
RequsetQueue:這是一個分發隊列,用來取Requst並在工做線程中執行,若是cache中找到就從cache中獲取response,沒有就獲取,而後將結果回傳到UI線程。異步
然而·Volley做爲優秀的網絡請求庫,是也能夠完成同步網絡請求,須要用到的類: RequestFuture。async
(同步請求就是,打個比方喊你過來,你不過來,我就一直喊,不走了(線程阻塞在那),直到你過來,調用OnResponse,你要是超過我設定的時間一直不過來,我就調用OnError;異步請求就是,我喊了一聲讓你過來,而後我就走了,至於啥時候過來我就無論了,你過來了,我就回調onResponse ,你不過來,我就回調onError)ide
RequestFuture工做原理:post
RxJava :借用扔物線的話url
一個詞:異步。
RxJava 在 GitHub 主頁上的自我介紹是 "a library for composing asynchronous and event-based programs using observable sequences for the Java VM"(一個在 Java VM 上使用可觀測的序列來組成異步的、基於事件的程序的庫)。這就是 RxJava ,歸納得很是精準。
然而,對於初學者來講,這太難看懂了。由於它是一個『總結』,而初學者更須要一個『引言』。
其實, RxJava 的本質能夠壓縮爲異步這一個詞。說到根上,它就是一個實現異步操做的庫,而別的定語都是基於這之上的。
換句話說,『一樣是作異步,爲何人們用它,而不用現成的 AsyncTask / Handler / XXX / ... ?』
一個詞:簡潔。
異步操做很關鍵的一點是程序的簡潔性,由於在調度過程比較複雜的狀況下,異步代碼常常會既難寫也難被讀懂。 Android 創造的 AsyncTask
和Handler
,其實都是爲了讓異步代碼更加簡潔。RxJava 的優點也是簡潔,但它的簡潔的不同凡響之處在於,隨着程序邏輯變得愈來愈複雜,它依然可以保持簡潔。
這是RxJava特性,具體移步 http://gank.io/post/560e15be2dca930e00da1083
好了,名詞解釋就到這。下面來回答問題,爲何要用Volley中的RequestFuture封裝RxJava來用異步請求處理同步請求?
換一種思考,爲何不用Volley中的RequestFuture封裝RxJava來用異步請求處理異步請求?聽起來更蠢對不對,異步,開一個線程,異步處理再開一個線程,這樣就開了兩個線程,很浪費對不對。
爲何不用Volley中的RequestFuture封裝RxJava來用同步請求異步處理請求?RxJava也能夠實現同步的,觀察者被觀察者放一個線程裏頭。以前用Volley都是異步請求,就實現了咱們想要的功能,爲何還要使用RxJava,還給同步了?咱們用RxJava由於它的異步+有條理,物盡其用呀。
這個算反證法吧,因此咱們用Volley中的RequestFuture封裝RxJava來用異步請求處理同步請求。
RxJava+Volley
public class RxRequest { /** * 發送post請求 * * @param url * @param target * @param <T> * @return */ public static <T> Observable<T> post(String url, Class<?> target) { return request(url, target, Request.Method.POST, new DefaultRetryPolicy()); } /** * 發送post請求 * * @param url * @param target * @param <T> * @return */ public static <T> Observable<T> post(String url, Class<?> target, RetryPolicy retryPolicy) { return request(url, target, Request.Method.POST, retryPolicy); } /** * 發送Get請求 * * @param url * @param target * @param <T> * @return */ public static <T> Observable<T> get(String url, Class<?> target) { return request(url, target, Request.Method.GET, new DefaultRetryPolicy()); } /** * 發送Get請求 * * @param url * @param target * @param <T> * @return */ public static <T> Observable<T> get(String url, Class<?> target, RetryPolicy retryPolicy) { return request(url, target, Request.Method.GET, retryPolicy); } public static <T> Observable<T> request(String url, Class<?> target, int method, RetryPolicy retryPolicy) { final RequestFuture<T> requestFuture = RequestFuture.newFuture(); final GsonRequest<T> request = new GsonRequest<T>(target, method, url, null, requestFuture, requestFuture); request.setRetryPolicy(retryPolicy); request.setTag(url); requestFuture.setRequest(request);//這是爲了下面的requestFuture.isCancelled return Observable.create(new Observable.OnSubscribe<T>() { @Override public void call(Subscriber<? super T> subscriber) { try { //只在被訂閱後才進行網絡請求處理 RequestManager.getRequestQueue().add(request); if (!subscriber.isUnsubscribed() && !requestFuture.isCancelled()) { subscriber.onNext(requestFuture.get());//阻塞,返回結果,喚醒 subscriber.onCompleted(); } } catch (Exception e) { subscriber.onError(e); } } }).subscribeOn(Schedulers.io());//開io線程,網絡請求 } /** * 取消請求 * * @param url */ public static void cancel(final String url) { RequestManager.getRequestQueue().cancelAll(new RequestQueue.RequestFilter() { @Override public boolean apply(Request<?> request) { return request.getTag().equals(url); } }); } }
activity(或fragment中)
RxRequest.<MyModel>post(url, MyModel.class)
.observeOn(AndroidSchedulers.mainThread())//觀察者在UI線程
.subscribe(new Subscriber<MyModel>() { @Override public void onCompleted() { Log.i("RxRequest", "onCompleted"); } @Override public void onError(Throwable e) { Log.e("RxRequest", "onError", e); } @Override public void onNext(MyModel myModel) { Log.i("RxRequest", "onNext==>" + myModel); } });