美文网首页
Retrofit+Okhttp+RxJava浅入浅出

Retrofit+Okhttp+RxJava浅入浅出

作者: 打酱油的小菜鸟 | 来源:发表于2023-10-18 17:55 被阅读0次

1.简单使用

//build.gradle中添加引用

    implementation("io.reactivex.rxjava2:rxjava:2.2.0")

    implementation("com.squareup.retrofit2:retrofit:2.2.0")

    implementation("com.squareup.retrofit2:converter-gson:2.2.0")

    implementation("com.squareup.retrofit2:adapter-rxjava2:2.2.0")

    implementation("com.jakewharton.retrofit:retrofit2-rxjava2-adapter:1.0.0")

    implementation("io.reactivex.rxjava2:rxandroid:2.0.1")

    implementation("com.squareup.okhttp3:logging-interceptor:3.4.1")

retrofit声明

var api = Retrofit.Builder()

        .client(client)

        //数据解析类,可以自定义。Retrofit2必须要指定,否则会报错

        .addConverterFactory(GsonConverterFactory.create())

        //不调用该方法或者不传入RxJava2CallAdapterFactory不能apiService中声明的方法不能返回Observable对象

        //只能返回Call对象

        .addCallAdapterFactory(RxJava2CallAdapterFactory.create())

        .baseUrl(baseUrl)

        .build()

        .create(clazz)

单独使用retrofit。getProject()返回Call对象

        api.getProject()

            .enqueue(object : Callback<String> {

                override fun onResponse(

                    call: Call<String>?,

                    response: Response<String>?) {

                    Log.w("demo", "MainActivity onResponse ${response?.body().toString()}")

                }

                override fun onFailure(call: Call<String>?, t: Throwable?) {

                    Log.w("demo", "MainActivity onFailure ${Log.getStackTraceString(t)}")

                }

            })

//配合rxJava使用,getProject()返回Observable对象

    api.getApiService()

            .getProject()

            .subscribeOn(Schedulers.io())

            .observeOn(AndroidSchedulers.mainThread())

            .subscribe (object : DefaultObserver<ProjectBean>() {

                override fun onSuccess(response: ProjectBean) {

                }

                override fun onFila(message: String?) {

                }

                override fun onFinish() {

               }

                override fun onException(msg: String?) {}

            })

2.源码解析

1. 通过构造者模式生成Retrofit对象

Retorfit.class

public Retrofit build() {

      if (baseUrl == null) {

      //判断baseUrl是否为空,为空抛出异常

        throw new IllegalStateException("Base URL required.");

      }

      okhttp3.Call.Factory callFactory = this.callFactory;

      if (callFactory == null) {

      //如果构建的时候没有调用client(),创建一个默认的clint

        callFactory = new OkHttpClient();

      }

      //如果构建时没有调用callbackExecutor(),android平台会创建一个默认的MainThreadExecutor

      Executor callbackExecutor = this.callbackExecutor;

      if (callbackExecutor == null) {

        callbackExecutor = platform.defaultCallbackExecutor();

      }

      // Make a defensive copy of the adapters and add the default Call adapter.

      //将构建时调用addCallAdapterFactory()的数据重新添加一次

      List<CallAdapter.Factory> adapterFactories = new ArrayList<>(this.adapterFactories);

      //添加一个默认的callAdapterFactory

      adapterFactories.add(platform.defaultCallAdapterFactory(callbackExecutor));

      // Make a defensive copy of the converters.

      //将构建时调用addConverterFactory()的数据重新添加一次,没有默认的数据转换工厂。

      List<Converter.Factory> converterFactories = new ArrayList<>(this.converterFactories);

      //返回Retrofit对象

      return new Retrofit(callFactory, baseUrl, converterFactories, adapterFactories,

          callbackExecutor, validateEagerly);

    }

2. 在create方法通过动态代理模式生成传入参数的对象。

Retrofit.class

public <T> T create(final Class<T> service) {

    Utils.validateServiceInterface(service);

    if (validateEagerly) {

    //检查代理类中的方法,一般不会走到这里

      eagerlyValidateMethods(service);

    }

    return (T) Proxy.newProxyInstance(service.getClassLoader(), new Class<?>[] { service },

        new InvocationHandler() {

          private final Platform platform = Platform.get();

          @Override public Object invoke(Object proxy, Method method, Object[] args)

              throws Throwable {

            // If the method is a method from Object then defer to normal invocation.

            if (method.getDeclaringClass() == Object.class) {

            //如果是Object.class中的方法,就走正常的反射调用。

            //例如没有重写过的getClass()

              return method.invoke(this, args);

            }

            if (platform.isDefaultMethod(method)) {

            //android不会走这里,可以忽略

              return platform.invokeDefaultMethod(method, service, proxy, args);

            }

            //ServiceMethod作用:将接口方法的调用转换为HTTP调用。

            //会将GET等注解转换成HTTP请求

            ServiceMethod<Object, Object> serviceMethod =

                (ServiceMethod<Object, Object>) loadServiceMethod(method);

            //实际请求类

            OkHttpCall<Object> okHttpCall = new OkHttpCall<>(serviceMethod, args);

            //绑定具体的请求类

            //根据addCallAdapterFactory()方法绑定的第一个CallAdapterFactory中get()方法返回的CallAdapter确定返回值

            //绑定RxJava2CallAdapterFactory的话返回值为Observable对象

            //如果不调用addCallAdapterFactory()方法默认返回Call对象

            return serviceMethod.callAdapter.adapt(okHttpCall);

          }

        });

  }

serviceMethod.callAdapter对象最后由Retrofit类中的nextCallAdapter()方法赋值

Retrofit.class

public CallAdapter<?, ?> nextCallAdapter(CallAdapter.Factory skipPast, Type returnType,

      Annotation[] annotations) {

    checkNotNull(returnType, "returnType == null");

    checkNotNull(annotations, "annotations == null");

    //skipPast为空,start从0开始

    int start = adapterFactories.indexOf(skipPast) + 1;

    for (int i = start, count = adapterFactories.size(); i < count; i++) {

    //返回adapterFactories中的第一个callAdapterFactory类中的get()方法返回的CallAdapter对象

      CallAdapter<?, ?> adapter = adapterFactories.get(i).get(returnType, annotations, this);

      if (adapter != null) {

        return adapter;

      }

    }

                    /*

                    省

                    略

                    代

                    码

                    */

}

3. 各CallAdapter中的adapt()方法

RxJava2CallAdapter.class

@Override

public Object adapt(Call<R> call) {

//根据是否异步创建不同的被观察者对象

    Observable<Response<R>> responseObservable = isAsync

        ? new CallEnqueueObservable<>(call)

        : new CallExecuteObservable<>(call);

    Observable<?> observable;

    if (isResult) {

      observable = new ResultObservable<>(responseObservable);

    } else if (isBody) {

      observable = new BodyObservable<>(responseObservable);

    } else {

      observable = responseObservable;

    }

                        /*

                        省

                        略

                        代

                        码

                        */

    //返回被观察者对象

    return observable;

  }

ExecutorCallAdapterFactory.class

public CallAdapter<?, ?> get(Type returnType, Annotation[] annotations, Retrofit retrofit) {

        if (getRawType(returnType) != Call.class) {

            return null;

        } else {

            final Type responseType = Utils.getCallResponseType(returnType);

            return new CallAdapter<Object, Call<?>>() {

                public Type responseType() {

                    return responseType;

                }

                public Call<Object> adapt(Call<Object> call) {

                    return new ExecutorCallbackCall(ExecutorCallAdapterFactory.this.callbackExecutor, call);

                }

            };

        }

    }

DefaultCallAdapterFactory.class

@Override

  public CallAdapter<?, ?> get(Type returnType, Annotation[] annotations, Retrofit retrofit) {

    if (getRawType(returnType) != Call.class) {

      return null;

    }

    final Type responseType = Utils.getCallResponseType(returnType);

    return new CallAdapter<Object, Call<?>>() {

      @Override public Type responseType() {

        return responseType;

      }

      @Override public Call<Object> adapt(Call<Object> call) {

        return call;

      }

    };

  }

4. 不使用RxJava进行请求,最后会调用到ExecutorCallbackCall类中的enqueue()或execute()。最后都会调用delegate对象的对应方法,而这个delegate对象其实就是第2点create()方法中的OkhttpCall对象

    ExecutorCallbackCall.class

    @Override

    public void enqueue(final Callback<T> callback) {

      if (callback == null) throw new NullPointerException("callback == null");

    //delegate其实就是Retrofit类create()方法中的的OkhttpCall对象

      delegate.enqueue(new Callback<T>() {

        @Override public void onResponse(Call<T> call, final Response<T> response) {

          callbackExecutor.execute(new Runnable() {

          //请求成功,切换线程,并将解析后的数据返回

          //如果build时没有调用callbackExecutor(),那么默认切换到主线程。

          //如果build时调用了callbackExecutor()了,则切换到指定线程

            @Override public void run() {

              if (delegate.isCanceled()) {

                // Emulate OkHttp's behavior of throwing/delivering an IOException on cancellation.

                callback.onFailure(ExecutorCallbackCall.this, new IOException("Canceled"));

              } else {

                callback.onResponse(ExecutorCallbackCall.this, response);

              }

            }

          });

        }

        @Override public void onFailure(Call<T> call, final Throwable t) {

          callbackExecutor.execute(new Runnable() {

          //请求失败,切换线程,并将错误信息返回

            @Override public void run() {

              callback.onFailure(ExecutorCallbackCall.this, t);

            }

          });

        }

      });

    }

    @Override

    public Response<T> execute() throws IOException {

    //和enqueue()方法一样的逻辑

      return delegate.execute();

    }

5. 使用RxJava进行请求。在调用subscribe()方法后才会进行请求。最后都会调用到CallEnqueueObservable或者CallExecuteObservable中的subscribeActual()方法中

Observabale.class

@Override

    public final void subscribe(Observer<? super T> observer) {

        ObjectHelper.requireNonNull(observer, "observer is null");

        try {

                                /*

                                省

                                略

                                代

                                码

                                */

            //这个是主要方法,这里会调用到具体的Observable类中

            //最后都会调用到CallEnqueueObservable或者CallExecuteObservable中的subscribeActual()方法中

            subscribeActual(observer);

        } catch (NullPointerException e) { // NOPMD

            throw e;

        } catch (Throwable e) {

            Exceptions.throwIfFatal(e);

            // can't call onError because no way to know if a Disposable has been set or not

            // can't call onSubscribe because the call might have set a Subscription already

            RxJavaPlugins.onError(e);

            NullPointerException npe = new NullPointerException("Actually not, but can't throw other exceptions due to RS");

            npe.initCause(e);

            throw npe;

        }

    }

CallEnqueueObservable.class

    @Override

    protected void subscribeActual(Observer<? super Response<T>> observer) {

    // Since Call is a one-shot type, clone it for each new observer.

    //originalCall其实就是adapt()中的OkHttpCall对象

    Call<T> call = originalCall.clone();

    CallCallback<T> callback = new CallCallback<>(call, observer);

    observer.onSubscribe(callback);

    //执行OkhttpCall中的enqueue()

    call.enqueue(callback);

  }

CallExecuteObservable.class

    @Override

    protected void subscribeActual(Observer<? super Response<T>> observer) {

    // Since Call is a one-shot type, clone it for each new observer.

    //originalCall其实就是adapt()中的OkHttpCall对象

    Call<T> call = originalCall.clone();

    observer.onSubscribe(new CallDisposable(call));

    boolean terminated = false;

    try {

    //执行OkhttpCall中的execute()

      Response<T> response = call.execute();

      if (!call.isCanceled()) {

        observer.onNext(response);

      }

      if (!call.isCanceled()) {

        terminated = true;

        observer.onComplete();

      }

    } catch (Throwable t) {

      Exceptions.throwIfFatal(t);

      if (terminated) {

        RxJavaPlugins.onError(t);

      } else if (!call.isCanceled()) {

        try {

          observer.onError(t);

        } catch (Throwable inner) {

          Exceptions.throwIfFatal(inner);

          RxJavaPlugins.onError(new CompositeException(t, inner));

        }

      }

    }

  }

6. OkhttpCall中做具体的同步或异步请求,并对请求回来的数据进行解析。

OkHttpCall.class

  @Override

  public void enqueue(final Callback<T> callback) {

    if (callback == null) throw new NullPointerException("callback == null");

    okhttp3.Call call;

    Throwable failure;

    synchronized (this) {

      if (executed) throw new IllegalStateException("Already executed.");

      executed = true;

      call = rawCall;

      failure = creationFailure;

      if (call == null && failure == null) {

        try {

        //生成RealCall对象

          call = rawCall = createRawCall();

        } catch (Throwable t) {

          failure = creationFailure = t;

        }

      }

    }

    if (failure != null) {

      callback.onFailure(this, failure);

      return;

    }

    if (canceled) {

      call.cancel();

    }

    //执行RealCall中的enqueue()进行真正的请求

    call.enqueue(new okhttp3.Callback() {

      @Override

      public void onResponse(okhttp3.Call call, okhttp3.Response rawResponse)

          throws IOException {

        Response<T> response;

        try {

        //解析请求返回的数据

          response = parseResponse(rawResponse);

        } catch (Throwable e) {

          callFailure(e);

          return;

        }

        //返回解析后的数据

        callSuccess(response);

      }

      @Override

      public void onFailure(okhttp3.Call call, IOException e) {

        try {

          callback.onFailure(OkHttpCall.this, e);

        } catch (Throwable t) {

          t.printStackTrace();

        }

      }

    });

  }

OkHttpCall.class

    @Override

    public Response<T> execute() throws IOException {

    okhttp3.Call call;

    synchronized (this) {

        /*省略代码*/

      call = rawCall;

      if (call == null) {

        try {

        //创建RealCall对象

          call = rawCall = createRawCall();

        } catch (IOException | RuntimeException e) {

          creationFailure = e;

          throw e;

        }

      }

    }

    if (canceled) {

      call.cancel();

    }

      //执行RealCall中的execute()进行真正的请求,并将返回的数据解析返回

    return parseResponse(call.execute());

  }

7.解析数据方法parseResponse()。

  OkHttpCall.class

  Response<T> parseResponse(okhttp3.Response rawResponse) throws IOException {

    ResponseBody rawBody = rawResponse.body();

        /*...省略代码...*/

    ExceptionCatchingRequestBody catchingBody = new ExceptionCatchingRequestBody(rawBody);

    try {

    //开始对数据进行解析

      T body = serviceMethod.toResponse(catchingBody);

      return Response.success(body, rawResponse);

    } catch (RuntimeException e) {

      // If the underlying source threw an exception, propagate that rather than indicating it was

      // a runtime exception.

      catchingBody.throwIfCaught();

      throw e;

    }

  }

ServiceMethod中的responseConverter对象最后由Retrofit类中的nextResponseBodyConverter()方法进行赋值。

ServiceMethod.class

R toResponse(ResponseBody body) throws IOException {

//调用指定的responseConverter进行数据解析,并返回

    return responseConverter.convert(body);

  }

Retrofit.class

public <T> Converter<ResponseBody, T> nextResponseBodyConverter(Converter.Factory skipPast,

      Type type, Annotation[] annotations) {

    checkNotNull(type, "type == null");

    checkNotNull(annotations, "annotations == null");

    //skopPast为空,start从0开始

    int start = converterFactories.indexOf(skipPast) + 1;

    for (int i = start, count = converterFactories.size(); i < count; i++) {

      Converter<ResponseBody, ?> converter =

          converterFactories.get(i).responseBodyConverter(type, annotations, this);

    /*如果build中没有调用addConverterFactory方法的话,converter对象为空。会抛出异常,所以addConverterFactory是必须指定的*/

      if (converter != null) {

        //noinspection unchecked

        return (Converter<ResponseBody, T>) converter;

      }

    }

    /**省略代码**/

  }

整个流程调用解析也就到此结束了,本篇暂不讨论RxJava其他操作符的使用。完结撒花!!!!!

相关文章

  • 深入浅出、深入深出、浅入浅出、浅入深出

    伊川思源实验学校 张文明 在网上读到这样一段话:世界上有四种老师,第一种是讲课能深入浅出,很深...

  • keystone浅入浅出

    在OpenStack的框架体系中Keystone的作用类似于一个服务总线,为OpenStack提供身份管理服务(I...

  • 《浅入浅出》-RocketMQ

    你知道的越多,你不知道的越多 点赞再看,养成习惯 本文GitHub https://github.com/Java...

  • 浅入浅出zookeeper

    zookeeper是我们日常开发中每天都能接触到的组件,但是好像很多人对其缺乏了解,所以心血来潮写了这篇文章。首先...

  • JVM浅入浅出

    说是浅入浅出,其实还是需要在入和出的过程中,进行一个深入的了解。在了解JVM之前,我其实是从比较常见的JVM面...

  • 世上有四种老师――顾明远

    1、深入浅出――轻负高效 2、深入深出――重负高效 3、浅入浅出――轻负低效 4、浅入深出――重负低效

  • 深入浅出

    文章有四种境界:深入浅出,深入深出,浅入浅出,浅入深出。深入浅出是最高境界,也最难。 没有对所论事物的深刻认识做不...

  • 浅入浅出Closures Expressions -- Swif

    Swift Syntax L3 -- Udacity 笔记 目录:1.浅入浅出Optional type2.浅入浅...

  • 浅入浅出Protocols & Extensions--

    Swift Syntax L2 -- Udacity 笔记 目录:1.浅入浅出Optional type2.浅入浅...

  • 浅入浅出监控系统

    如何搭建一个监控系统 生产环境必须是可监控的,一个对开发者黑盒的线上应用无异于灾难。 采集数据 保存数据 可视化数...

网友评论

      本文标题:Retrofit+Okhttp+RxJava浅入浅出

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