前几天健哥喊我研究一下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); } });