美文网首页Andriod收藏RxJAva OKHttp Retrofit深入浅出Android
OkRx扩展,让OkGo完美结合RxJava,比Retrofit

OkRx扩展,让OkGo完美结合RxJava,比Retrofit

作者: 廖子尧 | 来源:发表于2016-10-07 20:07 被阅读20862次

    OkGo - Rx扩展,可以方便的和RxJava联用,如果你熟悉Retrofit,那么这个框架和Retrofit使用方式很像。

    </br>

    以下是该项目相关文章的传送门:

    联系方式

    如何选择网络框架

    说了这么多功能,我们来看看为什么要使用OkGo这个框架。
    首先目前主流的几个网络框架

    • android-async-http
    • xUtils
    • volley
    • retrofit
    • okhttp

    在此引用知乎上Stay Zhang的回答:

    我们来先说一个常识性的错误:volley, retrofit, android-async-http 帮你封装了具体的请求,线程切换以及数据转换。而OkHttp 是基于http协议封装的一套请求客户端,虽然它也可以开线程,但根本上它更偏向真正的请求,跟HttpClient, HttpUrlConnection的职责是一样的。

    所以不要混淆。

    -----以下纯个人主观见解
    首先,我想即使你单纯使用OkHttp,还是会再包一层的,这样就等价于Volley之流的框架,只是封装的好与坏而已。

    android-async-http内部实现是基于HttpClient, 想必你肯定知道6.0之后HttpClient是不是系统自带的了,不过它在最近的更新中将HttpClient的所有代码copy了一份进来,所以还能使用。

    Volley是官方出的,volley在设计的时候是将具体的请求客户端做了下封装:HurlStack,也就是说可以支持HttpUrlConnection, HttpClient, OkHttp,相当于模版模式吧,这样解耦还是非常方便的,可以随意切换,如果你之前使用过Volley,并习惯使用,那直接写个OkHttp扩展就行了。

    Retrofit因为也是square出的,所以大家可能对它更崇拜些。Retrofit的跟Volley是一个套路,但解耦的更彻底:比方说通过注解来配置请求参数,通过工厂来生成CallAdapter,Converter,你可以使用不同的请求适配器(CallAdapter), 比方说RxJava,Java8, Guava。你可以使用不同的反序列化工具(Converter),比方说json, protobuff, xml, moshi等等。然而目前OkGo已经完全可以替代Retrofit,同样支持RxJava,但具有更强的灵活性和易用性。

    OkGo的优势

    • 优势一:性能高,专注于简单易用的网络请求,使用主流的okhttp进行封装,对于okhttp大家都知道,在Android4.4的源码中可以看到HttpURLConnection已经替换成OkHttp实现了,并且支持HTTP2/SPDY黑科技,支持socket自动选择最好路线,并支持自动重连,拥有自动维护的socket连接池,减少握手次数,拥有队列线程池,轻松写并发。
    • 优势二:特有的网络缓存模式,是大多数网络框架所不具备的,说一个应用场景,老板说我们的app不仅需要在有网的情况下展示最新的网络数据,还要在没网的情况下使用缓存数据,这时候是不是项目中出现了大量的代码判断当前网络状况,根据不同的状态保存不同的数据,然后决定是否使用缓存。细想一下,这是个通用的写法,于是OkGo提供了五种缓存模式,让你不用关心缓存的实现,而专注于数据的处理。(具体缓存的使用方法请看最后第四章节)。
    • 优势三:方便易用的扩展接口,可以添加全局的公共参数,全局拦截器,全局超时时间,更可以对单个请求定制拦截器,超时时间,请求参数修改等等,在使用上更是方便,原生支持的链式调用让你的请求更加清晰。
    • 优势四:强大的Cookie保持策略,我们知道在客户端对cookie的获取是个不太简单的事情,特别是还要处理cookie的过期时间,持久化策略等等,OkGo帮你彻底解决Cookie的难题,默认拥有内存存储和持久化存储两种实现,cookie全程自动管理,并且提供了额外的addCookie方式,允许介入到自动管理的过程中,添加你想创建的任何cookie。

    所以就说这么多啦,选最适合项目的,选大多数人选择的,选简单易用的,选择使用流行技术的,就这么个标准,而OkGo正是在这种情况下诞生啦!!

    OkRx目前支持

    • 完美结合RxJava
    • 比Retrofit更简单方便
    • 网络请求和RxJava调用,一条链点到底
    • 支持Json数据的自动解析转换
    • OkGo包含的所有请求功能,OkRx全部支持

    目前使用的RxJava版本如下

        compile 'io.reactivex:rxjava:1.2.0'
        compile 'io.reactivex:rxandroid:1.2.1'
    

    一.用法

    0.最开始的配置

    OkRxOkGo 的扩展,所以要想使用OkRx,那么请先按照OkGo的配置文档,做相应的初始化。

    1.在gradle中添加一行依赖

        compile 'com.lzy.net:okrx:0.1.0'  //Rx扩展
       
        或者
        
        compile 'com.lzy.net:okrx:+'      //使用+,引用最新版
    

    2.调用请求代码

    我们还是像正常使用OkGo的方式一样,传入我们需要请求的Url,和我们需要的参数,那么最关键的一行就是最后调用getCall()这个方法。

    这里传入的两个参数进行一下说明:

    • 第一个参数是Convert对象,表示需要将服务器返回的数据流解析成什么对象,这里我们先用最简单的String做转换,StringConvert对象也是库中内置的转换器。

    • 第二个参数是Adapter对象,表示需要将解析的结果用什么对象包装,该参数可以省略不写,那么默认是Call<T>这个对象包装,当然,我们要使用Rx的调用,使用这个肯定是不行的,所以我们传入OkRx扩展的RxAdapter对象,他是使用的Observable<T>对象包装的,同样他需要一个泛型,该泛型必须和Convert的泛型一致,否则就发生了类型转换异常。

      以上两个参数具体的注意事项我们后续详细再说。

     Observable<String> call = OkGo.post(Urls.URL_METHOD)//
                                        .headers("aaa", "111")//
                                        .params("bbb", "222")//
                                        .getCall(StringConvert.create(), RxAdapter.<String>create());
    

    3.调用Rx转换代码

    现在我们已经获取了Observable对象了,熟悉RxJava的你难道还不会使用了吗,以下是简单的在请求前弹出loading,结束后展示信息的代码。

    call.doOnSubscribe(new Action0() {
            @Override
            public void call() {
                showLoading();  //开始请求前显示对话框
            }
        })//
        .observeOn(AndroidSchedulers.mainThread())//切换到主线程
        .subscribe(new Action1<String>() {
            @Override
            public void call(String s) {
                dismissLoading();               //请求成功,关闭对话框
                handleResponse(s, null, null);
            }
        }, new Action1<Throwable>() {
            @Override
            public void call(Throwable throwable) {
                throwable.printStackTrace();
                dismissLoading();       //请求失败
                showToast("请求失败");
                handleError(null, null);
            }
        });
    

    4.代码整合

    上面的调用是不是很简单,有人可能觉得链试代码太长,没关系,我们完全可以像Retrofit一样,自己写一个ServerApi类,这里面管理了所有的接口请求和参数,只是OkGo并不是采用的注解和反射实现的,而是通过传参来实现,相信对你你来讲,这样的方式更加直观。我们再将调用配合上lambda表达式,那么最后的结果是这样的:

    这样的请求方式有没有惊艳到你!!

        OkGo.post(Urls.URL_METHOD)//
            .headers("aaa", "111")//
            .params("bbb", "222")//
            .getCall(StringConvert.create(), RxAdapter.<String>create())//以上为产生请求事件,请求默认发生在IO线程
            .doOnSubscribe(() -> {
                showLoading();  //开始请求前显示对话框
            })
            .observeOn(AndroidSchedulers.mainThread())//切换到主线程
            .subscribe(s -> {
                dismissLoading();               //请求成功,关闭对话框
                handleResponse(s, null, null);
            }, throwable -> {
                throwable.printStackTrace();
                dismissLoading();       //请求失败
                showToast("请求失败");
                handleError(null, null);
            });
    

    5。其他请求

    • 如果你想请求String,那么将第2步中的getCall方法,就是你想要的。
        getCall(StringConvert.create(), RxAdapter.<String>create())
    
    • 如果你想请求Bitmap,那么将第2步中的getCall方法,改成如下形式
        getCall(BitmapConvert.create(), RxAdapter.<Bitmap>create())
    
    • 如果你想下载File,那么还是修改这行
        getCall(new FileConvert(), RxAdapter.<File>create())
    
    • 如果你想直接解析Json对象,聪明的你一定知道还是这行。注意看Convert最后有个大括号,千万不能忘记
        getCall(new JsonConvert<ServerModel>() {}, RxAdapter.<ServerModel>create())
    
    • 如果你想直接解析List<Bean>对象,也很简单。注意看Convert最后有个大括号,千万不能忘记
        getCall(new JsonConvert<List<ServerModel>>() {}, RxAdapter.<List<ServerModel>>create())
    

    我想,对于一款普通的app,这些请求一定能满足你90%以上的需求,而且使用方便,只需要改一行代码,就能直接获取到你想要的数据。

    6.取消请求

    推荐对每一个网络请求的Subscription对象都交由统一的CompositeSubscription去管理,在界面销毁或者需要取消的地方调用。
    例如:在Activity中,当Activity销毁取消请求,可以在onDestory里面统一取消。

    @Override
    protected void onDestroy() {
        super.onDestroy();
    
        unSubscribe();
    }
    

    三、自定义Convert使用

    目前内部提供的包含Converter, StringConvert ,BitmapConvert ,FileConvert ,可以根据自己的需求去自定义Convert

    • Converter: 接口,所有转换器必须实现
    • StringConvert:将网络结果解析转成String
    • BitmapConvert:将网络结果解析转成Bitmap
    • FileConvert:将网络结果解析转成File

    对于自定义的JsonConvert,由于不同的业务实现都不一样,所以并不放在库中,提供参考实现供自己修改

    如果你觉得好或者给你带来了方便,请打赏一下给作者买杯咖啡喝吧。

    相关文章

      网友评论

      • b3f565d2994d:请问楼主还有没有打算一直维护这个框架?
        想在项目中使用这个框架,现在就是担心楼主是否一直在维护这个框架
      • smile_30ba:.doOnSubscribe(new Consumer() {
        @Override
        public void accept(@nonnull Disposable disposable) throws Exception {

        }
        })在哪个线程请求,这个accept()方法就执行在哪个线程,我的网络请求是单独分开的类,不在activity里,想问下怎么正确的切换这个方法所在线程呢
      • smile_30ba:我的网络请求封装在一个单独的类里面了,所以.doOnSubscribe()方法执行的线程就不是主线程了,能不能下面再加一句 .subscribeOn(AndroidSchedulers.mainThread()),来切换到主线程,会不会把网络请求的线程也切换到住县城了
      • LXC_Brian宣材:请问怎样能让get请求的url的中文不自动转码
      • CrazyCarrot:请求超时会崩溃,是我哪里没有处理吗?
      • 请叫我章鱼哥:大牛,问你个问题,我现在的项目已经导入了OKhttputil封装好的网络框架,但是看了你的OKGO觉得很不错,今天果断用了一下,我之前的项目中CallBack文件出了问题,日志如下

        Error:(126, 13) 错误: 方法不会覆盖或实现超类型的方法
        Error:(125, 9) 错误: <匿名com.****.wallet.net.okhttp.OkHttpUtils$2>不是抽象的, 并且未覆盖Callback中的抽象方法onResponse(Call,Response)
        D:\AndroidProject\ohePay2.0\app\src\main\java\com\ohepay\wallet\net\okhttp\OkHttpUtils.java
        Error:(132, 13) 错误: 方法不会覆盖或实现超类型的方法
        廖子尧: @王涛涛涛涛 详细加github首页qq群里交流吧。。
      • fancker:楼主您好 请问在 jsonCallback中如何用javabean的方法解析呢 能否给点小例子 谢谢啦
        廖子尧: @powerful_cat 详细加github首页qq群里交流吧。。
      • tedzyc:弱弱的问一下,支持对post方法做缓存吗,我知道retrofit对get方法的缓存支持很好。但是我这边服务器端对于读操作,也只提供post方法(xml的放在请求的body里的)
        廖子尧: @tedzyc 详细加github首页qq群里交流吧。。
        廖子尧: @tedzyc 缓存不分方法。任何方法都可以缓存。只要符合缓存条件。。
      • Tamic:仔细阅读源码后,封装效果还可以 但是;

        1 如果开发者想用Retroft怎么办?
        2 这种单列构建方式还适合目前的开发习惯吗
        3 最最最 想问的是 这个 Fast-Android-Networking 有啥却别,源码几乎一样的
        Tamic:@廖子尧 好吧 一款国外框架
        廖子尧:@Tamic Fast-Android-networking是什么东西。
      • b55ae2bc4c19:楼主写的非常好,但是在封装Rxjava的过程中缺乏了一个功能,没有实现类似全局过期token自动刷新,建议楼主参考http://alighters.com/blog/2016/08/22/rxjava-plus-retrofitshi-xian-zhi-demo/之后加进去。
        廖子尧: @b55ae2bc4c19 好的。。我需要看看有没有通用性。。如果涉及到业务逻辑只能放到demo中
      • 7aec83f88636:不错不错
      • 薄炳鑫:关注中
      • 傲慢的痞子:非常棒,很早就已经关注这个框架了,在研究研究,如果没什么问题就准备放到公司项目中,希望此框架能持续优化
        廖子尧: @傲慢的痞子 详细加github首页qq群里交流吧。。
      • Hemione:很有帮助,谢谢! :stuck_out_tongue_closed_eyes:

      本文标题:OkRx扩展,让OkGo完美结合RxJava,比Retrofit

      本文链接:https://www.haomeiwen.com/subject/qsnyyttx.html