Android RxVolley = Volley + RxJava + OkHttp
- RxVolley使用文档 V1.0:http://rxvolley.mydoc.io/
一.RxVolley使用指南
1.概述
RxVolley是一个基于Volley的网络请求库;同时支持RxJava;可以选择使用OKHttp替代默认的 HttpUrlConnection 做网络请求;可以选择使用图片加载功能(复用的网络请求将有效减少apk体积);移除了原Volley的 HttpClient 相关 API ,可在 API23 环境编译;内置了RxBus的实现,可有效替换掉EventBus等相关库;
2.依赖
使用RxVolley,需要在你的build.gradle文件中加入
compile 'com.kymjs.rxvolley:rxvolley:1.0.7'
如果你还想使用OKhttp来替代默认的HttpUrlconnection,需要加入
compile 'com.kymjs.rxvolley:okhttp:1.0.7'
如果你想使用RxVolley的图片加载功能(复用http模块可以有效减少apk大小),需要加入
compile 'com.kymjs.rxvolley:bitmapcore:1.0.7'
使用 RxVolley 做网络请求
3.简单实现
//get请求简洁版实现
RxVolley.get("http://www.kymjs.com/feed.xml", new HttpCallback() {
@Override
public void onSuccess(String t) {
Loger.debug("请求到的数据:" + t);
}
}); //post请求简洁版实现
HttpParams params = new HttpParams();
params.put("name", "kymjs");
params.put("age", );
params.put("image", new File("path"))//文件上传 RxVolley.post("http://kymjs.com/feed.xml", params, new HttpCallback() {
@Override
public void onSuccess(String t) {
Loger.debug("请求到的数据:" + t);
}
});
4.对Cookie等请求头的处理
//用户登录逻辑(HttpCallback中有很多重载方法,可以选择需要的实现)
HttpParams params = new HttpParams();
params.put("name", "kymjs");
params.put("age", );
params.put("password", "helloword");
RxVolley.post("http://kymjs.com/login", params, new HttpCallback() {
@Override
public void onSuccess(Map<String, String> headers, byte[] t) {
Loger.debug("请求到的数据:" + new String(t));
// 获取到的cookie
Loger.debug("===" + headers.get("Set-Cookie"));
}
});
//向服务器传递cookie信息
HttpParams params = new HttpParams();
params.put("name", "kymjs");
params.put("age", ); params.putHeaders("cookie", "your cookie"); RxVolley.post("http://kymjs.com/update", params, new HttpCallback() {
@Override
public void onSuccess(String t) {
Loger.debug("请求到的数据:" + t);
}
});
比起 入门 章节讲述的网络请求,你可能希望有更多的需求
5.构建网络请求
HttpParams params = new HttpParams(); //同之前的设计,传递 http 请求头可以使用 putHeaders()
params.putHeaders("cookie", "your cookie");
params.putHeaders("User-Agent", "rxvolley"); //传递 http 请求参数可以使用 put()
params.put("name", "kymjs");
params.put("age", ""); //http请求的回调,内置了很多方法,详细请查看源码
//包括在异步响应的onSuccessInAsync():注不能做UI操作
//网络请求成功时的回调onSuccess()
//网络请求失败时的回调onFailure():例如无网络,服务器异常等
HttpCallback callback = new HttpCallback(){
@Override
public void onSuccessInAsync(byte[] t) {
}
@Override
public void onSuccess(String t) {
}
@Override
public void onFailure(int errorNo, String strMsg) {
}
} ProgressListener listener = new ProgressListener(){
/**
* @param transferredBytes 进度
* @param totalSize 总量
*/
@Override
public void onProgress(long transferredBytes, long totalSize){
}
} new RxVolley.Builder()
.url("http://www.kymjs.com/rss.xml") //接口地址
//请求类型,如果不加,默认为 GET 可选项:
//POST/PUT/DELETE/HEAD/OPTIONS/TRACE/PATCH
.httpMethod(RxVolley.Method.GET)
//设置缓存时间: 默认是 get 请求 5 分钟, post 请求不缓存
.cacheTime()
//内容参数传递形式,如果不加,默认为 FORM 表单提交,可选项 JSON 内容
.contentType(RxVolley.ContentType.FORM)
.params(params) //上文创建的HttpParams请求参数集
//是否缓存,默认是 get 请求 5 缓存分钟, post 请求不缓存
.shouldCache(true)
.progressListener(listener) //上传进度
.callback(callback) //响应回调
.encoding("UTF-8") //编码格式,默认为utf-8
.doTask(); //执行请求操作
6.对 RxJava 的支持
RxVolley 支持返回一个 Observable 类型的数据,如下是 Result 类的原型
public class Result {
    public Map<String, String> header;
    public byte[] data;
    public Result(Map<String, String> header, byte[] data) {
        this.header = header;
        this.data = data;
    }
}
执行一次请求,并返回 Observable
Observable<Result> observable = new RxVolley.Builder()
.url("http://www.kymjs.com/rss.xml")
//default GET or POST/PUT/DELETE/HEAD/OPTIONS/TRACE/PATCH
.httpMethod(RxVolley.Method.POST)
.cacheTime() //default: get 5min, post 0min
.params(params)
.contentType(RxVolley.ContentType.JSON)
.getResult(); // 使用getResult()来返回RxJava数据类型 //当拿到 observable 对象后,你可以设置你自己的 subscriber
observable.subscribe(subscriber);
完整的使用示例
public class MainActivity extends AppCompatActivity {
    private Subscription subscription;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Observable<Result> observable = new RxVolley.Builder()
                .url("http://kymjs.com/feed.xml")
                .contentType(RxVolley.ContentType.FORM)
                .getResult();
        subscription = observable
                .map(new Func1<Result, String>() {
                    @Override
                    public String call(Result result) {
                        return new String(result.data);
                    }
                })
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Action1<String>() {
                    @Override
                    public void call(String result) {
                        Log.i("kymjs", "======网络请求" + result);
                    }
                });
    }
    @Override
    protected void onDestroy() {
        super.onDestroy();
        if (subscription != null && subscription.isUnsubscribed()) {
            subscription.unsubscribe();
        }
    }
}
7.自定义请求
也许你是 Volley 的重度使用者(就像我),那么你一定是因为 Volley 自由的扩展性而爱上它的。
你可以通过创建一个Request
RxVolley.Builder().setRequest(yourRequest).doTask();
去执行你的自定义 Request 一个典型自定义Request的示例:
/**
* Form表单形式的Http请求
*/
public class FormRequest extends Request<byte[]> { private final HttpParams mParams; public FormRequest(RequestConfig config, HttpParams params, HttpCallback callback) {
super(config, callback);
if (params == null) {
params = new HttpParams();
}
this.mParams = params;
} @Override
public String getCacheKey() {
if (getMethod() == RxVolley.Method.POST) {
return getUrl() + mParams.getUrlParams();
} else {
return getUrl();
}
} @Override
public String getBodyContentType() {
if (mParams.getContentType() != null) {
return mParams.getContentType();
} else {
return super.getBodyContentType();
}
} @Override
public ArrayList<HttpParamsEntry> getHeaders() {
return mParams.getHeaders();
} @Override
public byte[] getBody() {
ByteArrayOutputStream bos = new ByteArrayOutputStream();
try {
mParams.writeTo(bos);
} catch (IOException e) {
Loger.debug("FormRequest#getBody()--->IOException writing to ByteArrayOutputStream");
}
return bos.toByteArray();
} @Override
public Response<byte[]> parseNetworkResponse(NetworkResponse response) {
return Response.success(response.data, response.headers,
HttpHeaderParser.parseCacheHeaders(getUseServerControl(), getCacheTime(),
response));
} @Override
protected void deliverResponse(ArrayList<HttpParamsEntry> headers, final byte[] response) {
if (mCallback != null) {
HashMap<String, String> map = new HashMap<>(headers.size());
for (HttpParamsEntry entry : headers) {
map.put(entry.k, entry.v);
}
mCallback.onSuccess(map, response);
}
} @Override
public Priority getPriority() {
return Priority.IMMEDIATE;
}
}
8.文件(图片)下载
利用 RxVolley 的自定义请求,在库中内置了文件下载功能。你可以使用
//下载进度(可选参数,不需要可不传)
listener = new ProgressListener() {
@Override
public void onProgress(long transferredBytes, long totalSize) {
Loger.debug(transferredBytes + "======" + totalSize);
}
} //下载回调,内置了很多方法,详细请查看源码
//包括在异步响应的onSuccessInAsync():注不能做UI操作
//下载成功时的回调onSuccess()
//下载失败时的回调onFailure():例如无网络,服务器异常等
HttpCallback callback = new HttpCallback(){
@Override
public void onSuccessInAsync(byte[] t) {
}
@Override
public void onSuccess(String t) {
}
@Override
public void onFailure(int errorNo, String strMsg) {
}
} RxVolley.download(FileUtils.getSDCardPath() + "/a.apk",
"https://www.oschina.net/uploads/osc-android-app-2.4.apk",
listener, callback);
download()原型 
既然说了下载功能是利用 RxVolley 的自定义请求创建的,不妨看看他的方法实现:
/**
* 下载
*
* @param storeFilePath 本地存储绝对路径
* @param url 要下载的文件的url
* @param progressListener 下载进度回调
* @param callback 回调
*/
public static void download(String storeFilePath, String url, ProgressListener
progressListener, HttpCallback callback) {
RequestConfig config = new RequestConfig();
config.mUrl = url;
FileRequest request = new FileRequest(storeFilePath, config, callback);
request.setOnProgressListener(progressListener);
new Builder().setRequest(request).doTask();
}
9.更多可选设置
理论上来说,一切的请求设置都可以通过自定义 Request 来完成。
但是,如果你和我一样是个懒人,当然更希望这些早就有人已经做好了。
- 设置文件缓存的路径
默认的文件缓存路径是在SD卡根目录的 /RxVolley 文件夹下,你可以通过如下语句设置你的 cacheFolder
RxVolley.setRequestQueue(RequestQueue.newRequestQueue(cacheFolder));
需要注意的是,setRequestQueue 方法必须在 RxVolley.Build() 方法执行之前调用,也就是在使用 RxVolley 以前先设置配置信息。建议在 Application 类中完成这些设置。
- Https设置
如果不设置,默认信任全部的https证书。可以传入自定义 SSLSocketFactory
RxVolley.setRequestQueue(RequestQueue.newRequestQueue(cacheFolder), new HttpConnectStack(null, sslSocketFactory));
需要注意的是,setRequestQueue 方法必须在 RxVolley.Build() 方法执行之前调用,也就是在使用 RxVolley 以前先设置配置信息。建议在 Application 类中完成这些设置。 一个自定义设置SSLSocketFactory的相关示例:
//下载的证书放到项目中的assets目录中
InputStream ins = context.getAssets().open("app_pay.cer");
CertificateFactory cerFactory = CertificateFactory
.getInstance("X.509");
Certificate cer = cerFactory.generateCertificate(ins);
KeyStore keyStore = KeyStore.getInstance("PKCS12", "BC");
keyStore.load(null, null);
keyStore.setCertificateEntry("trust", cer); SSLSocketFactory socketFactory = new SSLSocketFactory(keyStore); RxVolley.setRequestQueue(RequestQueue.newRequestQueue(RxVolley.CACHE_FOLDER), new HttpConnectStack(null, sslSocketFactory));
Build()中的可选设置
详细请参阅 RxVolley$Builder 类中代码。
//请求超时时间
timeout() //为了更真实的模拟网络,如果读取缓存,延迟一段时间再返回缓存内容
delayTime() //缓存有效时间,单位分钟
cacheTime() //使用服务器控制的缓存有效期,即cookie有效期
//(如果使用服务器端控制,则无视#cacheTime())
useServerControl() //启用缓存
shouldCache() //重连策略,Volley默认的重连策略是timeout=3000,重试1次
retryPolicy()
二.Cookie持久化封装
RxVolley 默认对于 cookie 的操作是会从 HttpCallback 中返回 cookie,需要手动保存到本地。
如果你希望框架能够自动存储 cookie,可以这么做: 按需要选择继承FormRequest或者JsonRequest (直接继承 Request 类也可以,但是复杂) 并重写
@Override
protected void deliverResponse(ArrayList<HttpParamsEntry> headers, final byte[] response) {
if (mCallback != null) {
HashMap<String, String> map = new HashMap<>(headers.size());
for (HttpParamsEntry entry : headers) {
map.put(entry.k, entry.v);
}
mCallback.onSuccess(map, response);
}
}
逻辑如上述代码,其中的map即包含了服务器返回的cookie,可以做你自己的操作了。
最终执行你的自定义 Request
new RxVolley.Builder().setRequest(xxxxx).doTask();
在传递 Cookie 作为请求头的时候,建议写一个工具类,例如
public static HttpParams getHttpParams() {
    HttpParams params = new HttpParams();
    params.putHeader("cookie");
    return params;
}
三.使用 OkHttp
使用 OkHttp 替代HttpUrlconnection
Volley 允许你创建自己的网络请求执行器,执行器需要实现IHttpStack接口 RxVolley 的 okhttp module 已经有了使用 OkHttp 作为请求执行器的实现。 你可以使用如下代码设置,依旧需要注意的是,setRequestQueue 方法必须在 RxVolley.Build() 方法执行之前调用,也就是在使用 RxVolley 以前先设置配置信息。建议在 Application 类中完成这些设置。
RxVolley.setRequestQueue(RequestQueue.newRequestQueue(RxVolley.CACHE_FOLDER, new OkHttpStack(new OkHttpClient())));
使用 OkHttp 相关功能需要在你的 build.gradle 文件中加入
compile 'com.kymjs.rxvolley:okhttp:1.0.5'
四.Issue反馈
Android RxVolley = Volley + RxJava + OkHttp的更多相关文章
- RxVolley使用文档 —— RxVolley = Volley + RxJava + OkHttp
		RxVolley使用文档 -- RxVolley = Volley + RxJava + OkHttp 偶然有幸,看到这个框架,便深深的爱上了这个框架,赶紧转载一发到自己的博客上温故而知新,而且作者一 ... 
- 结合Retrofit,RxJava,Okhttp,FastJson的网络框架RRO
		Retrofit以其灵活的调用形式, 强大的扩展性著称. 随着RxAndroid的推出, Retrofit这样的可插拔式的网络框架因其可以灵活兼容各种数据解析器, 回调形式(主要还是RxJava啦)而 ... 
- Android开发学习之路-Android中使用RxJava
		RxJava的核心内容很简单,就是进行异步操作.类似于Handler和AsyncTask的功能,但是在代码结构上不同. RxJava使用了观察者模式和建造者模式中的链式调用(类似于C#的LINQ). ... 
- 给 Android 开发者的 RxJava 详解
		我从去年开始使用 RxJava ,到现在一年多了.今年加入了 Flipboard 后,看到 Flipboard 的 Android 项目也在使用 RxJava ,并且使用的场景越来越多 .而最近这几个 ... 
- Android - 使用Volley请求网络数据
		Android - 使用Volley请求网络数据 Android L : Android Studio 14 个人使用volley的小记,简述使用方法,不涉及volley源码 准备工作 导入Volle ... 
- okhttputils【 Android 一个改善的okHttp封装库】使用(一)
		版权声明:本文为HaiyuKing原创文章,转载请注明出处! 前言 本文使用的OKHttp封装库是张鸿洋(鸿神)写的,因为在项目中一直使用这个库,所以对于一些常用的请求方式都验证过,所以特此整理下. ... 
- okhttputils【 Android 一个改善的okHttp封装库】使用(三)
		版权声明:本文为HaiyuKing原创文章,转载请注明出处! 前言 这一篇主要讲一下将OkHttpUtils运用到mvp模式中. 数据请求地址:http://www.wanandroid.com/to ... 
- android ------- 开发者的 RxJava 详解
		在正文开始之前的最后,放上 GitHub 链接和引入依赖的 gradle 代码: Github: https://github.com/ReactiveX/RxJava https://github. ... 
- Retrofit2+Rxjava+OkHttp的使用和网络请求
		Retrofit2+Rxjava+OkHttp的使用和网络请求 https://blog.csdn.net/huandroid/article/details/79883895 加入Rxjava 如果 ... 
随机推荐
- 9.boost权重控制
			主要知识点: 学会在should中使用boost进行权重控制 假如现在有一个需求:要把should中某些字段优先显示, 1.不加boost权重控制 GET /forum/article/_se ... 
- Flask - WTF和WTForms创建表单
			目录 Flask - WTF和WTForms创建表单 一. Flask-WTF 1.创建基础表单 2.CSRF保护 3.验证表单 4.文件上传 5.验证码 二. WTForms 1. field字段 ... 
- 大专生自学Python到找到工作的心得
			先做个自我介绍,我13年考上一所很烂专科民办的学校,学的是生物专业,具体的学校名称我就不说出来献丑了.13年我就辍学了,我在那样的学校,一年学费要1万多,但是根本没有人学习,我实在看不到希望,我就退学 ... 
- BZOJ 2754 [SCOI2012]喵星球上的点名 (AC自动机、树状数组)
			吐槽: 为啥很多人用AC自动机暴力跳都过了?复杂度真的对么? 做法一: AC自动机+树状数组 姓名的问题,中间加个特殊字符连起来即可. 肯定是对点名串建AC自动机(map存儿子),然后第一问就相当于问 ... 
- 解析特殊格式的xml到map
			由于项目特殊,需要解析的xml文档样式特别,所以自己写了一个解析特殊xml的方法 先提供xml样式 <?xml version="1.0" encoding="UT ... 
- zookeeper监控之taokeeper
			1.taokeeper简介 淘宝的开源监控zookeeper的工具,年久失修! 项目地址: https://github.com/alibaba/taokeeper 监控项: CPU/MEM/LOAD ... 
- linux系统监控:记录用户操作轨迹,谁动过服务器
			1.前言 我们在实际工作当中,都碰到过误操作.误删除.误修改过配置文件等等事件.对于没有堡垒机的公司来说,要在linux系统上深究到底谁做过配置文件的修改.做过误删除是很头疼的事情,特别是遇到删库跑路 ... 
- 洛谷——P2676 超级书架
			https://www.luogu.org/problem/show?pid=2676#sub 题目描述 Farmer John最近为奶牛们的图书馆添置了一个巨大的书架,尽管它是如此的大,但它还是几乎 ... 
- [转]十五天精通WCF——第十天 学会用SvcConfigEditor来简化配置
			我们在玩wcf项目的时候,都是自己手工编写system.serviceModel下面的配置,虽然在webconfig中做wcf的服务配置的时候,vs提供大多 数的代码提示,但对于不太熟悉服务配置的小鸟 ... 
- 利用jQuery设计横/纵向菜单
			在网页中,菜单扮演着"指路者"的角色.怎样设计一个人性化的菜单呢.以下小编带着大家一起做. 效果图: watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi ... 
