美文网首页
RxJ2+Retrofit+OkHttp 学习分享(1)

RxJ2+Retrofit+OkHttp 学习分享(1)

作者: 姬94 | 来源:发表于2017-04-26 18:35 被阅读83次

    不用多说,先上 引入需要的包

     /*rx-android-java*/
        compile 'io.reactivex:rxjava:+'
        compile 'com.squareup.retrofit:adapter-rxjava:+'
        compile 'com.trello:rxlifecycle:+'
        compile 'com.trello:rxlifecycle-components:+'
        /*rotrofit*/
        compile 'com.squareup.retrofit2:retrofit:+'
        compile 'com.squareup.retrofit2:converter-gson:+'
        compile 'com.squareup.retrofit2:adapter-rxjava:+'
        compile 'com.google.code.gson:gson:+'
      /*Okhttp*/
        compile 'com.squareup.okhttp3:logging-interceptor:+'
    

    如果出现错误
    Warning:Conflict with dependency ‘com.google.code.findbugs:jsr305’. Resolved versions for app 异常

    在您的应用程序build.gradle 条件下面这段代码,亲测试。

    configurations.all { resolutionStrategy.force 'com.google.code.findbugs:jsr305:1.3.9'}
    

    第一步 我们要学习,Retrofit2.0 基本使用方式 我看的帖子简单好看的帖子,可以看下retrofit注解的意思就可以了。其余的咱们慢慢观察就可以了。

    接下来,我们需要学习一点,rxjava2的一些基础概念,因为需要用其实有个入门概念就好。
    快速通道我认为最简单,最快理解rxjava是个什么东西的帖子。
    解决办法上面帖子对map和flatmap解释并没有,但是把例子用了,可能会蒙圈解释的不能在清楚了。
    然后,Okhttp的学习点击这里是解释拦截器的,但是我感觉他帖子里的注释写的很棒,你看一遍就大概知道,OKhttp是怎么配置的了。毕竟,http就是网络配置的。
    (其实看不看都行,因为没有用db缓存优化,虽然源码有,但是我注释了)最后 咱们看一个数据库的配置文档greendao超级简单的操作手册,了解一点基础的东西,用于数据持久化(数据库层级的缓存)。我重点说一下,先编译一下,会自动生成几个操作类,文档有说明,不然数据库操作不了。

    在 RxJava 中,提供了一个名为 Scheduler 的线程调度器,RxJava 内部提供了4个调度器,分别是:

    Schedulers.io(): I/O 操作(读写文件、数据库、网络请求等),与newThread()差不多,区别在于io() 的内部实现是是用一个无数量上限的线程池,可以重用空闲的线程,因此多数情况下 io() 效率比 newThread() 更高。值得注意的是,在 io() 下,不要进行大量的计算,以免产生不必要的线程;
    Schedulers.newThread(): 开启新线程操作;
    Schedulers.immediate(): 默认指定的线程,也就是当前线程;
    Schedulers.computation():计算所使用的调度器。这个计算指的是 CPU 密集型计算,即不会被 I/O等操作限制性能的操作,例如图形的计算。这个 Scheduler 使用的固定的线程池,大小为 CPU 核数。值得注意的是,不要把 I/O 操作放在 computation() 中,否则 I/O 操作的等待时间会浪费 CPU;
    AndroidSchedulers.mainThread(): RxJava 扩展的 Android 主线程;

    首先盗图一张从原作者文章中盗图 其实我的分析主要来自原作者的文章原作者传送门

    盗图一张

    把原作者的,第一个功能的架子,已经他的类库我抽出来了。仅仅是为了看清楚结构。要是真正的使用还是用原作者的类库比较好。
    先看一张结果图。


    Paste_Image.png

    activity重点代码

    // 继承的类是Retrofit提供的。
    public class MainActivity extends RxAppCompatActivity 
    
    //单击事件的代码
      private void simpleDo() {
    //        一个接口实现类 其实最核心的目的就是实现,retrofit的方法url注入的。
            SubjectPostApi postEntity = new SubjectPostApi(this, simpleOnNextListener);
            postEntity.setAll(true);
            HttpManager manager = HttpManager.getInstance();
            manager.doHttpDeal(postEntity);
        }
    
        //   在主线程的函数回调,用于回写数据。
        HttpOnNextListener simpleOnNextListener = new HttpOnNextListener<List<SubJectResulte>>() {
            @Override
            public void onNext(List<SubJectResulte> subjects) {
                tvMsg.setText("网络返回:\n" + subjects.toString());
            }
    
            @Override
            public void onCacheNext(String cache) {
                /*缓存回调*/
                Gson gson = new Gson();
                java.lang.reflect.Type type = new TypeToken<BaseResultEntity<List<SubJectResulte>>>() {
                }.getType();
                BaseResultEntity resultEntity = gson.fromJson(cache, type);
                tvMsg.setText("缓存返回:\n" + resultEntity.getData().toString());
            }
    
            /*用户主动调用,默认是不需要覆写该方法*/
            @Override
            public void onError(Throwable e) {
                super.onError(e);
                tvMsg.setText("失败:\n" + e.toString());
            }
    
            /*用户主动调用,默认是不需要覆写该方法*/
            @Override
            public void onCancel() {
                super.onCancel();
                tvMsg.setText("取消請求");
            }
        };
    
    

    SubjectPostApi.class 重点代码 返回接口是一个观察者其实就是数据集合

    public class SubjectPostApi extends BaseApi
    //设置调用的URL方法,其实就是retrofit注入方法。这里就可以获得了你要用的那个rul 重写了这个方法。
        @Override 
        public Observable getObservable(Retrofit retrofit) {
            HttpPostService service = retrofit.create(HttpPostService.class);
            return service.getAllVedioBys(isAll());
        }
    

    利索的看一下, HttpPostService是什么,很简单,他是一个接口就是Retrofit封装的一个url接口,通过他我们获得网络资源。。。巨简单。

    public interface HttpPostService {
        @POST("AppFiftyToneGraph/videoLink")
        Call<RetrofitEntity> getAllVedio(@Body boolean once_no);
    
        @POST("AppFiftyToneGraph/videoLink")
        Observable<RetrofitEntity> getAllVedioBy(@Body boolean once_no);
    
        @FormUrlEncoded
        @POST("AppFiftyToneGraph/videoLink")
        Observable<BaseResultEntity<List<SubJectResulte>>> getAllVedioBys(@Field("once") boolean once_no);
    }
    
    

    接着看看抽象类 BaseApi。这个类,这个类比较大,但是抽取重点代码就可以了,这里有个一个BaseResultEntity参数对象 后面会介绍 ,这个类其实就是关于retrofit 网络设置以及 rxjava的一个组合类 重点我们看到了。Func1这个接口他就是实现观察者的重要一个方法。从retrofit得到BaseResultEntity类型的数据 然后解释出去。

    public abstract class BaseApi<T> implements Func1<BaseResultEntity<T>, T> 
    一个重点参数,这个属性就是,最上面,在activity实现接口,参数回调,那必然也是这里实现的。
        private SoftReference<HttpOnNextListener> listener;
    //重载了一个call方法,这个不用解释了吧,大名鼎鼎的call 就是把结果一个一个输出出来
     @Override
        public T call(BaseResultEntity<T> httpResult) {
            if (httpResult.getRet() == 0) {
                throw new HttpTimeException(httpResult.getMsg());
            }
            return httpResult.getData();
        }
    

    一眼可以看完的,BaseResultEntity 实体类

    public class BaseResultEntity<T> {
        //    错误判断
        private int ret;
        // 提示信息
        private String msg;
        //    返回的数据
        private T data;
    ....显示get和set方法
    }
    

    然后咱们看看 先看抽象类HttpOnNextListener 很明显,就是定义了一点点方法。

    public abstract class HttpOnNextListener<T> {
        /**
         * rejava 制定下一个的方法
         */
    
        public abstract void onNext(T t);
    
        /**
         * 缓冲返回结果
         */
    
        public void onCacheNext(String string) {
    
        }
    
        /**
         * 成功后的ober返回,扩展链接式调用 观察者的模式
         */
        public void onNext(Observable observable) {
    
        }
    
        /**
         * 失败或错误调用的方法
         */
        public void onError(Throwable e) {
    
        }
    
        /***
         * 取消回调方法
         *
         * */
        public void onCancel() {
    
        }
    
    }
    

    重点大戏来了。HttpManager 类 这是最重要的一个方法。也是我们注入的这个合并的核心方法。 OkHttpClient 获得网络资源 retrofit获取接口结果 Observable提供数据 subscriber 解析 httpOnNextListener 回调会写到界面中。

    /**
         * 处理http请求
         *
         * @param basePar 封装的请求数据
         */
        public void doHttpDeal(BaseApi basePar) {
            OkHttpClient.Builder builder = new OkHttpClient.Builder();
            builder.connectTimeout(basePar.getConnectionTime(), TimeUnit.SECONDS);
    //        添加拦截器 为了例子简单,暂时注释 db持久化数据存储。仅仅是一个缓存的优化方案。
    //        builder.addInterceptor(new CookieInterceptor(basePar.isCache(), basePar.getUrl()));
            if (RxRetrofitApp.isDebug()) {
                builder.addInterceptor(getHttpLoggingInterceptor());
            }
    
            /*创建retrofit对象*/
            Retrofit retrofit = new Retrofit.Builder()
    //                客户端塞进去,这里是OKhttp和retrofit结合
                    .client(builder.build())
    // 适配器就是解释在rxjava中是不是见过Call方法的,看到了吗。
                    .addCallAdapterFactory(RxJavaCallAdapterFactory.create())
                    .baseUrl(basePar.getBaseUrl())
                    .addConverterFactory(GsonConverterFactory.create())
                    .build();
            /*rx处理 订阅者 数据的解析方式,这个类其实也简单 稍后会解释*/
            ProgressSubscriber subscriber = new ProgressSubscriber(basePar);
    //        被订阅者
            Observable observable = basePar.getObservable(retrofit)
                    /*失败后的retry配置*/
                    .retryWhen(new RetryWhenNetworkException(basePar.getRetryConut(),
                            basePar.getRetryDelay(), basePar.getRetryIncreateDalay()))
                    /*生命周期管理*/
    //                .compose(basePar.getRxAppCompatActivity().bindToLifecycle())
                    .compose(basePar.getRxAppCompatActivity().bindUntilEvent(ActivityEvent.PAUSE))
                    /*http请求线程*/
                    .subscribeOn(Schedulers.io())
                    .unsubscribeOn(Schedulers.io())
                    /*回调线程*/
                    .observeOn(AndroidSchedulers.mainThread())
                    /*结果判断 内容解析 这里就获得了数据*/
                    .map(basePar);
    
     /*链接式对象返回 其实在这里这句并没有什么卵用。。。呵呵呵。*/ 
            SoftReference<HttpOnNextListener> httpOnNextListener = basePar.getListener();
            if (httpOnNextListener != null && httpOnNextListener.get() != null) {
                httpOnNextListener.get().onNext(observable);
            }
    
            /*数据回调 订阅*/
            observable.subscribe(subscriber);
    
        }
    

    最后是ProgressSubscriber 其实他就是一个观察者。因为他继承了Subscriber 看看他的重点代码

    public class ProgressSubscriber<T> extends Subscriber<T>
    //这个监听 传来传去,最终,转到的他调用的地方。很不容易 
       private SoftReference<HttpOnNextListener> mSubscriberOnNextListener;
    
    //重写 next方法,这里的就是最终解释的方法 其他的什么准备呀,开始呀,异常呀其实都可以忽略,因为核心是他。
      @Override
        public void onNext(T t) {
            if (mSubscriberOnNextListener.get() != null) {
                mSubscriberOnNextListener.get().onNext(t);
            }
        }
    
    

    琐碎但是也是需要知道的几个代码
    这个篇幅我并没有说GreenDAO在哪里用,源码是是有一层数据库缓存的设计思路。但是为了篇幅的思考方式我想着,这一层有没有其实不印象了解,整体的搭建。我会在后面进行解释。提一点,我们的activity 用的是RxAppCompatActivity 这个类。怕你们没有注意,我单独说一下。

    好了。那么这个框架怎么用,我们要做什么东西?
    其实,,咱们在鲁一下,进行拓展,多要干什么的代码?
    第一步,添加接口 HttpPostService 把你要实现的url写进去,或者你单独写一个,也是可以的,
    第二步,我们先显示一个 继承 BaseApi 类的代码 重写 方法,把第一步,实现的url输入进去

    public Observable getObservable(Retrofit retrofit) 
    

    第三步,在你的activtiy中实现一个类似这个样的方法,把你第二步的url注入到httpmanager中。

    private void simpleDo() {
    //        一个接口实现类 其实最核心的目的就是实现,retrofit的方法url注入的。
            SubjectPostApi postEntity = new SubjectPostApi(this, simpleOnNextListener);
            postEntity.setAll(true);
            HttpManager manager = HttpManager.getInstance();
            manager.doHttpDeal(postEntity);
        }
    

    第四步:当然就是,HttpOnNextListener 这个监听 可以实现这样的一个匿名类,也可以自己写一个类,然后在向上转型,都是妥妥的。

    //   在主线程的函数回调,用于回写数据。
        HttpOnNextListener simpleOnNextListener = new HttpOnNextListener<List<SubJectResulte>>() {
            @Override
            public void onNext(List<SubJectResulte> subjects) {
                tvMsg.setText("网络返回:\n" + subjects.toString());
            }
    
            @Override
            public void onCacheNext(String cache) {
                /*缓存回调*/
                Gson gson = new Gson();
                java.lang.reflect.Type type = new TypeToken<BaseResultEntity<List<SubJectResulte>>>() {
                }.getType();
                BaseResultEntity resultEntity = gson.fromJson(cache, type);
                tvMsg.setText("缓存返回:\n" + resultEntity.getData().toString());
            }
    
            /*用户主动调用,默认是不需要覆写该方法*/
            @Override
            public void onError(Throwable e) {
                super.onError(e);
                tvMsg.setText("失败:\n" + e.toString());
            }
    
            /*用户主动调用,默认是不需要覆写该方法*/
            @Override
            public void onCancel() {
                super.onCancel();
                tvMsg.setText("取消請求");
            }
        };
    

    最基本的一套 合并及时专业的。我感觉,大神写库很好用考虑的很周到,修改起来吧,也很简单。再次提供大神传送地址,比我写的好传送门 大神的下载地址,他的博客有,
    我项目的目录结构是这样的,比较特别是吧,主要是,我没有按照mvc方式写,而是按照 我引入类的前后顺序写的,类似思路导图的方式写的,用起来不好,仅仅是方便我个人理解类的前后关系。

    我的项目目录结构

    我的源码

    相关文章

      网友评论

          本文标题:RxJ2+Retrofit+OkHttp 学习分享(1)

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