美文网首页Android开发经验谈Android进阶之路
Retrofit源码主线逻辑简单分析---------stay教

Retrofit源码主线逻辑简单分析---------stay教

作者: 上官若枫 | 来源:发表于2018-03-27 10:15 被阅读251次

    此篇文章根据stay课程做的笔记,只是大概讲解了一下retrofit的整的流程,细节处尚未做分析。视频地址http://www.stay4it.com/my/course/22

    基本网络请求workflow

    所有的网络框架请求基本都会遵循下图的workflow,retrofit也不例外,retrofit是一个类型安全的http请求框架,因为它声明了泛型,因此在使用过程中,外层不需要考虑数据的反序列化,框架会通过converter实现。


    image.png

    1.request:封装request,加入请求队列。由注解实现,通过配置请求参数实现request的封装,好处是以后在改动过程中,只需要改动底层,上层不用改。
    2.executor:进入looper循环,如果有空闲线程,就执行http请求。这里是retrofit的关键封装,由calladapter将call转化成相应的泛型T
    3.HTTP Call:拿到服务器,bytes流,进行反序列化,未做封装主要有OKhttp实现
    4.数据返回:回到上层,进行UI刷新,将二进制流做序列化处理,converter转换成想要的对象

    sample

    Retrofit retrofit = new Retrofit.Builder()
                            .baseUrl(INewsApi.HOST)
                            .client(builder.build())
                            .addConverterFactory(GsonConverterFactory.create())
                            .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
                            .build();
    

    build方法

    retrofit是通过build模式获取了实例,下面是retrofit的build方法的思维导图,讲解了大致的retrofit创建实例的过程


    image.png
    public Retrofit build() {
          if (baseUrl == null) {
            throw new IllegalStateException("Base URL required.");
          }
    
          okhttp3.Call.Factory callFactory = this.callFactory;
          if (callFactory == null) {
            callFactory = new OkHttpClient();
          }
    
          Executor callbackExecutor = this.callbackExecutor;
          if (callbackExecutor == null) {
            callbackExecutor = platform.defaultCallbackExecutor();
          }
    
          // Make a defensive copy of the adapters and add the default Call adapter.
          List<CallAdapter.Factory> adapterFactories = new ArrayList<>(this.adapterFactories);
          adapterFactories.add(platform.defaultCallAdapterFactory(callbackExecutor));
    
          // Make a defensive copy of the converters.
          List<Converter.Factory> converterFactories = new ArrayList<>(this.converterFactories);
    
          return new Retrofit(callFactory, baseUrl, converterFactories, adapterFactories,
              callbackExecutor, validateEagerly);
        }
    
    

    可以从代码中看到retrofit对象的建立大概分为六个参数,这里着重讲四个
    callFactory :说明现如今retrofit只支持OKhttpclient
    converterFactories :扩展功能,gsonfactory等等
    callbackExecutor :这个参数主要是将提供一个主线程
    adapterFactories:传入了callbackExecutor 参数,里面还会有一个方法是将传入的call类型(其实实际上是OKhttpcall)转化为call,里面最重要的是将利用callbackExecutor 将子线程里的东西转化为主线程。当执行onresponse()方法时,就会回到上层的call.enqueue()方法,从而拿到数据。

    create方法

    这个方法主要是创造相应的API实例对象,这里也是从主线讲大概。下图为create方法的流程图


    image.png
    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, @Nullable Object[] args)
                  throws Throwable {
                // If the method is a method from Object then defer to normal invocation.
                if (method.getDeclaringClass() == Object.class) {
                  return method.invoke(this, args);
                }
                if (platform.isDefaultMethod(method)) {
                  return platform.invokeDefaultMethod(method, service, proxy, args);
                }
                ServiceMethod<Object, Object> serviceMethod =
                    (ServiceMethod<Object, Object>) loadServiceMethod(method);
                OkHttpCall<Object> okHttpCall = new OkHttpCall<>(serviceMethod, args);
                return serviceMethod.callAdapter.adapt(okHttpCall);
              }
            });
      }
    

    这里主要采用了动态代理模式,当api调用相应的方法后,动态代理会进行拦截操作,将接口中的方法注解取出来,适配成OKhttpcall,这个过程主要由servicemethod方法来完成,后来将servicemethod方法作为参数传入OKhttp中,构成实例,最后将OKhttpcall转化为call,进而和上面ExecutorCallAdapterFactory类相连接,完成数据的接收工作。


    2018/03/28更新补充笔记-------------从细节处看retrofit

    create():

     ServiceMethod<Object, Object> serviceMethod =(ServiceMethod<Object,Object>)loadServiceMethod(method);
     OkHttpCall<Object> okHttpCall = new OkHttpCall<>(serviceMethod, args);
     return serviceMethod.callAdapter.adapt(okHttpCall);
    

    ①servicemethod:带缓存的注解解析类,里面的loadServiceMethod()方法中含有serviceMethodCache。作为缓存,因此不会重复解析api中的方法。

    Servicemethod.java

    这个类比较关键,是通过builder模式创建的实例,看一下build方法
    callAdapter = createCallAdapter():calladapter是调用了retrofit.callAdapter()方法获得的

    接下来回到retrofit类中的callAdapter方法
    nextCallAdapter()——>通过遍历adapterFactories确定项目所需要的calladapter

    adapterFactories又是从何而来的呢,还记得在retrofit的build方法中传入的那几个参数吗,其中有一个就是adapterFactories,这个类包含三种(java,rxjava,android)通过每个factory的get方法来确定,API到底是最后要的是那个类型,observerble还是call。这里以call类型作为参考。

    因此带有calladapter的servicemethod就生成了

    然后来看第三行代码就是adapter中的adapt方法

    我们刚刚说了,这个servicemethod中的adapter是默认的ExecutorCallAdapterFactory,然后来看adapt方法。
    它将callbackExecutor和传进来的OKhttpcall一同传入到ExecutorCallbackCall中,这个OKhttpcall参数后来变成了delegate,然后执行了enqueue方法。然后又将重点引入到了OKhttpcall中的enqueue方法中,走到这一步已经脱离了retrofit,进入到了OKhttp中
    在okhttpcall中还有一个enqueue方法,这个实现类属于OKhttp的realcall方法

     @Override public void enqueue(Callback responseCallback) {
        synchronized (this) {
          if (executed) throw new IllegalStateException("Already Executed");
          executed = true;
        }
        captureCallStackTrace();
        eventListener.callStart(this);
        client.dispatcher().enqueue(new AsyncCall(responseCallback));
      }
    

    这里的realcall的enqueue方法引入了AsyncCall这个异步的call类,当然还有execute同步方法是直接执行的请求操作。

    然后回到刚刚ExecutorCallAdapterFactory类中,里面delegate的enqueue方法传入了一个callback,里面使用到了主线程callbackExecutor,将OKhttpcall中的子线程操作转移到了主线程中

    // 创建 网络请求接口 的实例
            GetRequest_Interface request = retrofit.create(GetRequest_Interface.class);
    
            //对 发送请求 进行封装
            Call<Reception> call = request.getCall();
            call.enqueue(new Callback<Translation>() {
                //请求成功时回调
                @Override
                public void onResponse(Call<Translation> call, Response<Translation> response) {
                    //请求处理,输出结果
                    response.body().show();
                }
    
                //请求失败时候的回调
                @Override
                public void onFailure(Call<Translation> call, Throwable throwable) {
                    System.out.println("连接失败");
                }
            });
    

    以上为一个小的例子,这里的call就是通过create创造出来的包含泛型的ExecutorCallbackCall,继而调用它内部的enqueue方法,将数据拿到主线程中

    相关文章

      网友评论

        本文标题:Retrofit源码主线逻辑简单分析---------stay教

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