美文网首页网络
RxJava+Retrofit+MVP学习笔记

RxJava+Retrofit+MVP学习笔记

作者: 刘喵喵嗷呜 | 来源:发表于2019-07-12 13:55 被阅读0次

    学习链接,都是跟着大佬一步步来的,本篇主要是自己的笔记
    RxJava和Retrofit最近超火,不学不是人。

    首先关于RxJava

    概念

    官方定义是罗里吧嗦一大堆看不懂,主要看这两个词就够了,异步,基于事件。

    • 观察者设计模式
      RxJava是基于观察者和被观察者模式,观察者和被观察者之间存在一种订阅的关系,观察者可以知道被观察者某种事件下所发生的一切。


      观察者模式
    • 基于事件
      你老婆拿着你的工资卡去商场购物,买了一个两万块钱的包包,这时候你就可以收到银行发来的一条消费两万元的短信,这个时候你就是观察者,你老婆就是被观察者。
      但你不可能观察你老婆所有的事情吧,比如问了个路、喝了杯咖啡等等,这些你老婆不告诉你你是不会知道的,你能知道的仅仅是你老婆花了两万块钱买了个很贵的包而已。
      凡是你卡里余额变动,你都能知道,我们可以说这是基于银行卡余额变动事件下的观察者模式。总结四个字:基于事件。

    • 异步
      RxJava它是异步的。这个比较好理解,就好像我去蛋糕店买蛋糕,我跟老板说了我想要什么样的蛋糕,然后我告诉老板我什么时候来取,不必一直在蛋糕店里等着,我可以去忙其它的事,这就是异步。

    • 操作符转变
      被观察者是可以通过某种操作符转变的,就是用一个操作符可以把被观察者改变的意思.....
      RxJava中也内置了许多操作符,可以把被观察者进行转变,转变为另外一种形态以后在研究..

    创建一个观察者模式

    1.创建被观察者。
    ObservableEmitter有三种的方法,

    • void onNext(T value),方法可以无限调用
    • void onError(Throwable error),不可以重复调用
    • void onComplete(),OnComplete可以重复调用,但是Observer(观察者)只会接收一次
    Observable<String> observable = Observable.create(new ObservableOnSubscribe<String>() {
                @Override
                public void subscribe(ObservableEmitter<String> emitter) throws Exception {
                     //把这个消息发送出去。
                    emitter.onNext("我花了两万块钱买了个包");
                }
            });
    

    2.创建观察者。

    Observer<String> observer = new Observer<String>() {
                @Override
                public void onSubscribe(Disposable d) {
    
                }
    
                @Override
                public void onNext(String msg) {
                    //你收到买包的消息。
                    Log.e("RxJava--------------",msg);
                    //你暗骂的话。
                    Log.e("RxJava--------------","收到了,败家娘们");
    
                }
    
                @Override
                public void onError(Throwable e) {
    
                }
    
                @Override
                public void onComplete() {
    
                }
            };
    

    3.订阅

    //订阅。
    observable.subscribe(observer);
    

    RxJava2.0的异步和链式编程

    前言里面有提到,RxJava是支持异步的
    需要Scheduler。Scheduler,英文名调度器,它是RxJava用来控制线程。
    当我们没有设置的时候,RxJava遵循哪个线程产生就在哪个线程消费的原则,也就是说线程不会产生变化,始终在同一个。
    RxJava后台执行,前台调用,这个原则,我们需要调用observeOn(AndroidSchedulers.mainThread()),observeOn是事件回调的线程,AndroidSchedulers.mainThread()一看就知道是主线程,subscribeOn(Schedulers.io()),subscribeOn是事件执行的线程,Schedulers.io()是子线程,这里也可以用Schedulers.newThread(),只不过io线程可以重用空闲的线程,因此多数情况下 io() 比 newThread() 更有效率。前面的代码根据异步和链式编程的原则,我们可以写成

     Observable.create(new ObservableOnSubscribe<String>() {
                @Override
                public void subscribe(ObservableEmitter<String> emitter) throws Exception {
                    emitter.onNext("1");
                    emitter.onNext("2");
                    emitter.onNext("3");
                    emitter.onComplete();
                }
            })
                    .observeOn(AndroidSchedulers.mainThread())//回调在主线程
                    .subscribeOn(Schedulers.io())//执行在io线程
                    .subscribe(new Observer<String>() {
                        @Override
                        public void onSubscribe(Disposable d) {
                            Log.e(TAG,"onSubscribe");
                        }
                        @Override
                        public void onNext(String value) {
                            Log.e(TAG,"onNext:"+value);
                        }
                        @Override
                        public void onError(Throwable e) {
                            Log.e(TAG,"onError="+e.getMessage());
                        }
    
                        @Override
                        public void onComplete() {
                            Log.e(TAG,"onComplete()");
                        }
                    });
    

    关于Retrofit的

    Retrofit其实我们可以理解为OkHttp的加强版,它也是一个网络加载框架。底层是使用OKHttp封装的。准确来说,网络请求的工作本质上是OkHttp完成,而 Retrofit 仅负责网络请求接口的封装。它的一个特点是包含了特别多注解,方便简化你的代码量。并且还支持很多的开源库(著名例子:Retrofit + RxJava)。

    优点

    • 超级解耦
    • 可以配置不同HttpClient来实现网络请求,如OkHttp、HttpClient...
    • 支持同步、异步和RxJava
    • 可以配置不同的反序列化工具来解析数据,如json、xml...
    • 请求速度快,使用非常方便灵活

    使用

    1.创建Retrofit对象,采用建造者模式。

    Retrofit retrofit = new Retrofit.Builder()
            //设置baseUrl,baseUrl+接口中配置的地址组成真正的请求地址。
            .baseUrl("http://wanandroid.com/")
            .client(new OkHttpClient())
            .build();
    
    

    2.创建请求接口,这里是通过注解的方式获取到请求类型,参数等信息,所有的请求参数都可以在这里进行配置,然后框架层根据这些信息封装成一个Request对象,发给服务端

    public interface WanAndroidService {
        /**
         * 获取公众号列表
         * @Call<ResponseBody>
         */
        @GET("wxarticle/chapters/json")
        //baseUrl+接口中配置的地址组成真正的请求地址。
        Call<ResponseBody> getPublicAccountList();
    }
    

    3.创建请求接口对象。

    WanAndroidService service = retrofit.create(WanAndroidService.class);
     
     Call<ResponseBody> responseBodyCall = service.getPublicAccountList();
    

    4.发送

     responseBodyCall.enqueue(new Callback<ResponseBody>() {
                @Override
                public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
                    try {
                        Log.e("玩Android数据-------",response.body().string());
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
    
                @Override
                public void onFailure(Call<ResponseBody> call, Throwable t) {
    
                }
            });
    

    两者怎么结合呢?

    Retrofit retrofit = new Retrofit.Builder()
            //设置baseUrl,baseUrl+接口中配置的地址组成真正的请求地址。
            .baseUrl("http://wanandroid.com/")
            .client(new OkHttpClient())
            .addConverterFactory(GsonConverterFactory.create()) // 支持Gson解析
            .addCallAdapterFactory(RxJava2CallAdapterFactory.create()) // 支持RxJava2
            .build();
    
    public interface WanAndroidService {
        /**
         * 获取公众号列表
         * @return  Observable<PublicAccountBean>
         */
        @GET("wxarticle/chapters/json")
        Observable<PublicAccountBean> getPublicAccountList();
    }
    

    GsonConverterFactory的作用是将请求的结果转化成具体的JavaBean。至于Observable,是不是很熟悉?对,它就是RxJava中的被观察者,RxJava2CallAdapterFactory是将该javaBean的对象再封装成Observable,中间经历了两次转化。让我们看下最终的调用:

     WanAndroidService service = retrofit.create(WanAndroidService.class);
            service.getPublicAccountList()
                    .subscribeOn(Schedulers.io())
                    .observeOn(AndroidSchedulers.mainThread())
                    .subscribe(new Observer<PublicAccountBean>() {
                        @Override
                        public void onSubscribe(Disposable d) {
    
                        }
    
                        @Override
                        public void onNext(PublicAccountBean publicAccountBean) {
                            //请求成功
                            for (int i = 0; i < publicAccountBean.getData().size(); i++) {
                                Log.e("data----------", publicAccountBean.getData().get(i).getName());
                            }
    
                        }
    
                        @Override
                        public void onError(Throwable e) {
                            //失败
                        }
    
                        @Override
                        public void onComplete() {
                        }
                    });
    

    封装

    封装net

    首先创建一个Retrofit管理类,将Retrofit、OkHttpClient和请求接口的构建放一起。

    public class RetrofitManager {
        private Retrofit mRetrofit;
    
        private static class InstanceHelper {
            static RetrofitManager instance = new RetrofitManager();
        }
    
        public static RetrofitManager getInstance() {
            return InstanceHelper.instance;
        }
    
        private RetrofitManager() {
            mRetrofit = new Retrofit.Builder()
                    //设置baseUrl
                    .baseUrl("http://wanandroid.com/")
                    //设置OkHttpClient对象
                    .client(createOkhttpClient())
                    .addCallAdapterFactory(RxJava2CallAdapterFactory.create()) // 支持RxJava
                    .addConverterFactory(GsonConverterFactory.create()) // 支持Gson解析
                    .addConverterFactory(ScalarsConverterFactory.create())//支持字符串
                    .build();
        }
    
        /*
        * 创建OkHttpClient对象。Retrofit底层基于OkHttpClient进行网络请求。
        * */
        private OkHttpClient createOkhttpClient() {
            HttpLoggingInterceptor httpLoggingInterceptor = new HttpLoggingInterceptor();
            httpLoggingInterceptor.setLevel(BuildConfig.DEBUG ? HttpLoggingInterceptor.Level.BODY : HttpLoggingInterceptor.Level.NONE);
            return new OkHttpClient.Builder()
                    //设置连接超时时间
                    .connectTimeout(30, TimeUnit.SECONDS)
                    //设置读取超时时间
                    .readTimeout(30, TimeUnit.SECONDS)
                    .writeTimeout(30, TimeUnit.SECONDS)
                    //添加日志过滤器
                    .addInterceptor(httpLoggingInterceptor)
                    //添加BaseInterceptor过滤器
                    .addInterceptor(new BaseInterceptor())
                    .build();
        }
    
        public <T> T createApi(final Class<T> service) {
            return mRetrofit.create(service);
        }
    }
    
    

    接着是创建请求接口API
    三行代码完成get post设置,被监听的设置,参数的设置 。

    public interface API {
        /**
         * 获取公众号列表
         * @return  Observable<PublicAccountBean>
         */
        @POST("wxarticle/chapters/json")
        @FormUrlEncoded
        Observable<PublicAccountBean> getPublicAccountList(@FieldMap Map<String, String> map);
    }
    

    BaseInterceptor是用来添加公共参数和头部等,get和post方法添加的方法不一样所以要区分。

    public class BaseInterceptor implements Interceptor {
    //    这里分了POST和GET等其它请求,POST和GET添加请求头和添加参数的代码不同,所以得判断请求的method。
        @NonNull
        @Override
        public Response intercept(Chain chain) throws IOException {
            Request request = chain.request();
            //POST请求
            if (request.method().equals("POST")) {
                FormBody formBody = null;
                FormBody.Builder bodyBuilder = new FormBody.Builder();
                if (request.body() instanceof FormBody) {
                    formBody = (FormBody) request.body();
                    //把原来的参数添加到新的构造器,(因为没找到直接添加,所以就new新的)
                    for (int i = 0; i < formBody.size(); i++) {
                        bodyBuilder.add(formBody.name(i), formBody.value(i));
                    }
                    //添加公共参数
                    formBody = bodyBuilder
                            .add("pubParam1", "1")
                            .add("pubParam2", "2")
                            .add("pubParam3", "3")
                            .build();
    
                    //添加请求头
                    request = request
                            .newBuilder()
                            .post(formBody)
                            .addHeader("Content-Type", "application/json;charset=UTF-8")
                            .addHeader("User-Agent", "android")
                            .build();
                }
                return chain.proceed(request);
            } else {
                //添加公共参数
                HttpUrl.Builder urlBuilder = request.url()
                        .newBuilder()
                        .addQueryParameter("pubParam1", "1")
                        .addQueryParameter("pubParam2", "2")
                        .addQueryParameter("pubParam3", "3");
    
                //添加请求头
                Request.Builder newBuilder = request.newBuilder()
                        .method(request.method(), request.body())
                        .url(urlBuilder.build())
                        .addHeader("Content-Type", "application/json;charset=UTF-8")
                        .addHeader("User-Agent", "android");
    
                return chain.proceed(newBuilder.build());
            }
    
        }
    
    }
    

    框架搭建差不多就是这样了。之后就是直接使用就行啦。

    相关文章

      网友评论

        本文标题:RxJava+Retrofit+MVP学习笔记

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