RxVolley使用文档 —— RxVolley = Volley + RxJava + OkHttp


偶然有幸,看到这个框架,便深深的爱上了这个框架,赶紧转载一发到自己的博客上温故而知新,而且作者一开头,就来了这么一句:

Retrofit? No, I like Volley.

看到这句,我嘴角勾起了一抹微笑,嘿嘿,我也很喜欢Volley呀,而网上二次封装的Volley库,感觉不是那么的尽人意,而自己封装的,也只够自己在项目中使用罢了!我们先来看下他的Github地址:

而我们的这篇博文是参照他的中文文档来的,我纯属搬运工

一.RxVolley使用指南

1.概述

RxVolley是一个基于Volley的网络请求库;同时支持RxJava;可以选择使用OKHttp替代默认的 HttpUrlConnection 做网络请求;可以选择使用图片加载功能(复用的网络请求将有效减少apk体积);移除了原VolleyHttpClient 相关 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", 18);
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", 18);
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", 100);

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", "18");

//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(6)
    //内容参数传递形式,如果不加,默认为 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(6) //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接口

RxVolleyokhttp 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反馈

使用过程中如果有什么好的建议欢迎反馈给原作者

再次声明哈,我特别喜欢这个框架,在我博客上发布,如果有侵权行为,请告知我删除!

RxVolley使用文档 —— RxVolley = Volley + RxJava + OkHttp的更多相关文章

  1. Android RxVolley = Volley + RxJava + OkHttp

    Github:https://github.com/kymjs/RxVolley RxVolley使用文档 V1.0:http://rxvolley.mydoc.io/ 一.RxVolley使用指南 ...

  2. ReactiveX/RxJava文档中文版

    项目地址:https://github.com/mcxiaoke/RxDocs,欢迎Star和帮忙改进. 有任何意见或建议,到这里提出 Create New Issue 阅读地址 ReactiveX文 ...

  3. Retrofit 简介 wiki 文档

    简介 Type-safe HTTP client for Android and Java by Square, Inc. GitHub主页:https://github.com/square/ret ...

  4. Android开发阅读文档资源

    Android Studio:工具:http://developer.android.com/intl/zh-cn/tools/studio/index.html培训教程:http://develop ...

  5. 接口文档神器Swagger(下篇)

    本文来自网易云社区 作者:李哲 二.Swagger-springmvc原理解析 上面介绍了如何将springmvc和springboot与swagger结合,通过简单配置生成接口文档,以及介绍了swa ...

  6. Spring Boot文档

    本文来自于springboot官方文档 地址:https://docs.spring.io/spring-boot/docs/current/reference/html/ Spring Boot参考 ...

  7. PHP初中高级学习在线文档下载

    收集了一些框架的学习文档与手册,视频教程,给大家带来了更多的方便,只要收藏与保存于百度云盘就好了,省去了网上到处寻找的时间!大家有需要就收藏保存起来吧! 如果不能下载请到群内获取新的下载地址 QQ群 ...

  8. iot平台异构对接文档

    iot平台异构对接文档 准备工作 平台提供的XAgent开发指南.pdf demo程序xagent-ptp-demo 平台上添加产品得到产品id和key 部署时需要插件的基础程序<xlink-x ...

  9. Java 设置、删除、获取Word文档背景(基于Spire.Cloud.SDK for Java)

    本文介绍使用Spire.Cloud.SDK for Java 提供的BackgroundApi接口来操作Word文档背景的方法,可设置背景,包括设置颜色背景setBackgroundColor().图 ...

随机推荐

  1. 81. Search in Rotated Sorted Array II (中等)

    Suppose an array sorted in ascending order is rotated at some pivot unknown to you beforehand. (i.e. ...

  2. thinkphp零碎小知识

    在使用thinkphp搭建后台的时候,有很多的参数需要去配置,有的记不住还要去查找,这里把一些基本的参数整理一下,还有些零碎的知识点,与大家共勉,希望能方便大家. 友情提示:这些配置是 thinkph ...

  3. python 类属性.方法 实例的基本用法

    class man(): classify = "people"# 全局属性 def __init__(self,name,age,value,):#类方法 self.name = ...

  4. UDP网络编程

    概念: UDP协议(用户数据报协议)是无连接,不可靠的,无序的.速度比较快, UDP协议以数据报作为数据传输的载体 进行数据传输时,首先将传输的数据定义成数据报(Datagram),在数据报中指明数据 ...

  5. ActiveMQ消息传递的两种方式

    1.什么是ActiveMQ? ActiveMQ是apache提供的开源的,实现消息传递的一个中间插件,可以和spring整合,是目前最流行的开源消息总线,ActiveMQ是一个完全支持JMS1.1和J ...

  6. Win10 下Cmake编译配置 Opencv3.1 + Cuda7.5 + VS2013

    折腾了三天终于配置成功了,在此写下编译配置的全部步骤和遇到的很多坑. 整体介绍: OpenCV 中 CUDA 实现的函数还不是太多,使用前要在OpenCV的官网上确认以下你想要的功能是否已经实现,否则 ...

  7. Git 常用命令速查表

  8. Android简易实战教程--第四十六话《RecyclerView竖向和横向滚动》

    Android5.X后,引入了RecyclerView,这个控件使用起来非常的方便,不但可以完成listView的效果,而且还可以实现ListView无法实现的效果.当然,在新能方便也做了大大的提高. ...

  9. Android 开发环境的搭建(新环境)

    最近想往Android 转型,所以又重新捡起Android学习.看了一下各位大神的文章,说的比较乱,因为版本不一样所以搭建过程也不一样,我在这里说一下最简单快捷的方式.(PS:那时候搭建环境好复杂啊, ...

  10. DragVideo,一种在播放视频时,可以任意拖拽的方案

    转载请把头部出处链接和尾部二维码一起转载,本文出自逆流的鱼yuiop:http://blog.csdn.net/hejjunlin/article/details/53638896 前言 项目已开源到 ...