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. expect IDENTIFIER, actual IDENTIFIER 处理

    涉及到注入数据库的报错,这是很常见的了. 但是期望IDENTIFIER,实际IDENTIFIER 的报错,你们知道是什么意思吗? 我已开始看到的时候,是mybatis报错发神经了,报错了报错.再跑一次 ...

  2. day0203 XML 学习笔记

    day02, 03 1. xml语言和作用 2. xml语法详解 2.1 xml 语法声明 2.1.1 encoding 属性 2.1.2 standalone 属性 2.2 xml 元素(Eleme ...

  3. Kali安装使用文泉驿字体

    安装文泉驿字体 Kali选择"简体中文"安装后,在终端等地方发现字体总有重叠,只要安装中文字体即可,这里推荐文泉驿字体.文泉驿是一个以开发开源.免费中文电子资源--如汉字字体.词库 ...

  4. 解决Error: ENOENT: no such file or directory, scandir 'D:\IdeaWork\code-front-jet\node_modules\.npminstall\node-sass\3.7.0\node-sass\vendor'

    在使用npm安装node-sass的时候,可能会出现如下的报错: Error: ENOENT: no such file or directory, scandir 'D:\IdeaWork\code ...

  5. C++框架_之Qt的窗口部件系统的详解-上

    C++框架_之Qt的窗口部件系统的详解-上 第一部分概述 第一次建立helloworld程序时,曾看到Qt Creator提供的默认基类只有QMainWindow.QWidget和QDialog三种. ...

  6. Linux设置文件读写权限

    设置文件夹的读写权限: sudo chmod -R 777 /data 权限码描述 sudo chmod 600 ××× (只有所有者有读和写的权限)sudo chmod 644 ××× (所有者有读 ...

  7. Go 语言 goto 语句

    Go 语言的 goto 语句可以无条件地转移到过程中指定的行. goto语句通常与条件语句配合使用.可用来实现条件转移, 构成循环,跳出循环体等功能. 但是,在结构化程序设计中一般不主张使用goto语 ...

  8. Docker容器的运用

    Docker 利用容器来运行应用. 容器是从镜像创建的运行实例.它可以被启动.开始.停止.删除.每个容器都是相互隔离的.保证安全的平台. 可以把容器看做是一个简易版的 Linux 环境(包括root用 ...

  9. JAVA Eclipse使用Maven构建web项目详解(SSM框架)

    tips: 启动项目后,welcome-file的链接即为测试用例 部署maven web项目 Eclipse使用Maven构建web项目详解 pom.xml添加webapp依赖: <depen ...

  10. JFinal中使用QuartzPlugin报ClassCastException解决方法

    JDK1.8中泛型反射修改对旧版本的影响 本文地址:http://blog.csdn.net/sushengmiyan 本文作者:苏生米沿 问题复现环境: JDK1.8 JFinal1.9 quart ...