美文网首页
Retrofit执行流程

Retrofit执行流程

作者: 帝都老机长 | 来源:发表于2016-11-09 14:19 被阅读0次

    Retrofit执行流程

    注:(本人英文有限,翻译不正确请见谅)

    1.Retrofit初始化

    我将Retrofit封装在Application中初始化,这里就不贴代码了

    (1) 初始化信息解读:
        public Retrofit getRetrofit(String host) {
            if (!mRetrofitMap.containsKey(host)) {
                Retrofit retrofit = new Retrofit.Builder()   //(建造者模式,其实我也对设计模式不是很了解,初始化Retrofit基本信息)
                        .baseUrl(host)      //请求host地址
                        .addConverterFactory(GsonConverterFactory.create())   // 增加对服务器返回json数据解析库
                        .client(createHttpClient())   //创建httpClient 进行网络请求发送
                        .build();           //这里进行了Retrofit初始化
                mRetrofitMap.put(host, retrofit);
    
                if (mAPIService == null)
                    mAPIService = retrofit.create(APIService.class);   //这块使用注解 + 动态代理 简化网络请求配置,APIService必须是接口模式
            }
            return mRetrofitMap.get(host);
        }
    
    (2) 在调用中执行至Retrofit.Builder初始化方法:
    Builder(Platform platform) {
          // 记录当前运行平台,我们当然是Android平台啦 参考类 Platform.Android
          this.platform = platform;
          // Add the built-in converter factory first. This prevents overriding its behavior but also
          // ensures correct behavior when using converters that consume all types.
          // 预加载一个对服务器内容解析类,防止某些意外发生
          converterFactories.add(new BuiltInConverters());
        }
    

    返回(1)

    (3) 创建HttpClient:
     private OkHttpClient createHttpClient() {
            OkHttpClient.Builder mHttpClientBuilder = new OkHttpClient.Builder();
            mHttpClientBuilder.connectTimeout(LocalAppConfig.CONNET_TIME_OUT, TimeUnit.SECONDS)  //设置超时时间
                    .addInterceptor(mCacheHeaderInterceptor)  //增加请求头缓存拦截器
                    .addInterceptor(mAddParamsInterceptor)    //增加请求头参数拦截器
                    .addNetworkInterceptor(mAddHeaderTypeInterceptor)   //增加请求头参数配置拦截器
                    .addNetworkInterceptor(new StethoInterceptor())     //增加StethoInterceptor拦截器
                    .addNetworkInterceptor(mRequestLogInterceptor());   //自定义拦截器做你想做的事
            return mHttpClientBuilder.build();
        }
    

    拦截器支持多种添加,根据需求添加即可,符合语法即可

    返回(1)

    (4) 我的理解拦截器模式是在进行某些初始化前准备数据处理 增加异常过滤等

    当前代码段:Retrifit.Builder.build()

        /**
         * Create the {@link Retrofit} instance using the configured values.
         * <p>
         * Note: If neither {@link #client} nor {@link #callFactory} is called a default {@link
         * OkHttpClient} will be created and used.
         */
        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) {
            // 前面介绍我们所属的平台属于Android平台,此记录网络请求回调在MainThread线程中执行
            callbackExecutor = platform.defaultCallbackExecutor();
          }
    
          // Make a defensive copy of the adapters and add the default Call adapter.
          List<CallAdapter.Factory> adapterFactories = new ArrayList<>(this.adapterFactories);
          // 添加默认CallAdapter工厂适配器 ExecutorCallAdapterFactory 注:后面会频繁至这个类进行信息获取
          adapterFactories.add(platform.defaultCallAdapterFactory(callbackExecutor));
    
          // Make a defensive copy of the converters.
          List<Converter.Factory> converterFactories = new ArrayList<>(this.converterFactories);
    
          //初始化Retrofit,此方法参数 全部赋值给即将创建Retrofit对象,持有之前介绍所有的引用
          return new Retrofit(callFactory, baseUrl, converterFactories, adapterFactories,
              callbackExecutor, validateEagerly);
        }
      }
    

    返回(1)

    (5)Retrofit注解及动态代理

    前面提到的APIService,必须是接口模式,且使用Retrofit预先定义的注解,如:@GET ,@QueryMap等。

    public interface APIService {
        @GET("movie/index")
        Call<LocalResponse<List<MovieResponse>>> loadingMovies(@QueryMap Map<String, String> map);
    }
    
    5.1当前代码段:Retrofit.create()

    先介绍个概念:
    动态代理 : 通过这种方式,被代理的对象(RealSubject)可以在运行时动态改变,需要控制的接口(Subject接口)可以在运行时改变,控制的方式(DynamicSubject类)也可以动态改变,从而实现了非常灵活的动态代理关系。

    public <T> T create(final Class<T> service) {
        Utils.validateServiceInterface(service);    //检测service即上文提到的APIService是否是接口
        if (validateEagerly) {
          eagerlyValidateMethods(service);
        }
        //动态代理,每次调用请求接口类中的方法最终都会执行至此,进行动态绑定执行,例如 APIService.loadingMovies()
        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) {
                  return method.invoke(this, args);
                }
                if (platform.isDefaultMethod(method)) {
                  return platform.invokeDefaultMethod(method, service, proxy, args);
                }
                
                 // 代码跟踪进去看,最终执行至  result = new ServiceMethod.Builder(this, method).build(); 又是一个建造者
                ServiceMethod serviceMethod = loadServiceMethod(method);  
                // OkHttpCall 是最终调用OkHttp发送请求的封装类
                OkHttpCall okHttpCall = new OkHttpCall<>(serviceMethod, args);
                
                // 调用至 new ExecutorCallbackCall<>(callbackExecutor, call);
                return serviceMethod.callAdapter.adapt(okHttpCall);
              }
            });
      }
    
    5.2当前代码段:ServiceMethod.Builder.build()
    public ServiceMethod build() {
          // 这里同样需要追踪代码,最后又调用Retrofit.nextCallAdapter()方法 阅读下段代码分析
          callAdapter = createCallAdapter();
          
          // 获取在接口注解定义的服务器返回值类型
          responseType = callAdapter.responseType();
          if (responseType == Response.class || responseType == okhttp3.Response.class) {
            throw methodError("'"
                + Utils.getRawType(responseType).getName()
                + "' is not a valid response body type. Did you mean ResponseBody?");
          }
          
          // 同获取默认工厂适配器类似,此处获取相应对服务器数据解析类,
          // 前面有个默认添加的BuiltInConverters及我们自行添加的GsonConverterFactory两个解析类
          responseConverter = createResponseConverter();
    
          .....
          
          // 初始化ServiceMethod实例,一个请求会有一个ServiceMethod及OkHttpCall对应
          return new ServiceMethod<>(this);
        }
    

    初始化ServiceMethod 函数调用栈:
    Retrofit.loadServiceMethod --> new ServiceMethod.Builder(this, method).build() --> ServiceMethod.Builder.createCallAdapter() --> retrofit.callAdapter(returnType, annotations) -->Retrofit.nextCallAdapter()

    5.3当前代码段:Retrofit.nextCallAdapter()
    private final List<CallAdapter.Factory> adapterFactories;
    
    public CallAdapter<?> nextCallAdapter(CallAdapter.Factory skipPast, Type returnType,
          Annotation[] annotations) {
        checkNotNull(returnType, "returnType == null");
        checkNotNull(annotations, "annotations == null");
    
        int start = adapterFactories.indexOf(skipPast) + 1;    
        for (int i = start, count = adapterFactories.size(); i < count; i++) {
          CallAdapter<?> adapter = adapterFactories.get(i).get(returnType, annotations, this);
          if (adapter != null) {
            // 从当前Retrofit List<CallAdapter.Factory>遍历出CallAdapter,即之前添加的ExecutorCallAdapterFactory.get(returnType, annotations, this);
            return adapter;
          }
        }
        ......
      }
    
    5.4当前代码段:ExecutorCallAdapterFactory.get()
    public CallAdapter<Call<?>> get(Type returnType, Annotation[] annotations, Retrofit retrofit) {
        if (getRawType(returnType) != Call.class) {
          return null;
        }
        final Type responseType = Utils.getCallResponseType(returnType);
        return new CallAdapter<Call<?>>() {
          @Override public Type responseType() {
            return responseType;
          }
    
          @Override public <R> Call<R> adapt(Call<R> call) {
            return new ExecutorCallbackCall<>(callbackExecutor, call);
          }
        };
    

    上段代码遍历最后筛选出CallAdapter

    5.5当前代码段:ExecutorCallAdapterFactory.ExecutorCallbackCall
    static final class ExecutorCallbackCall<T> implements Call<T> {
        final Executor callbackExecutor;
        final Call<T> delegate;
    
        ExecutorCallbackCall(Executor callbackExecutor, Call<T> delegate) {
          // callbackExecutor 主线程执行回调Executor 
          // delegate 动态代理实例化的OkHttpCall实例
          this.callbackExecutor = callbackExecutor;
          this.delegate = delegate;
        }
        
        //进一步调用OkHttpCall发送网络请求的核心方法之一
        @Override public void enqueue(final Callback<T> callback) {
          if (callback == null) throw new NullPointerException("callback == null");
    
          delegate.enqueue(new Callback<T>() {
            @Override public void onResponse(Call<T> call, final Response<T> response) {
              callbackExecutor.execute(new Runnable() {
                @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);
                }
              });
            }
          });
        }
        ......
      }
    
    5.6当前代码段:OkHttpCall.enqueue()

    OkHttp Call 请求的发送与接收处理

    @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 {
              call = rawCall = createRawCall();
            } catch (Throwable t) {
              failure = creationFailure = t;
            }
          }
        }
    
        if (failure != null) {
          callback.onFailure(this, failure);
          return;
        }
    
        if (canceled) {
          call.cancel();
        }
    
        // 异步请求处理
        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();
            }
          }
    
          private void callFailure(Throwable e) {
            try {
              callback.onFailure(OkHttpCall.this, e);
            } catch (Throwable t) {
              t.printStackTrace();
            }
          }
    
          private void callSuccess(Response<T> response) {
            try {
              callback.onResponse(OkHttpCall.this, response);
            } catch (Throwable t) {
              t.printStackTrace();
            }
          }
        });
      }
     
      private okhttp3.Call createRawCall() throws IOException {
        // 根据参数组装一个请求request
        Request request = serviceMethod.toRequest(args);
        // 最终实例化OkHttp的Call对象进行网络请求
        okhttp3.Call call = serviceMethod.callFactory.newCall(request);
        if (call == null) {
          throw new NullPointerException("Call.Factory returned null.");
        }
        return call;
      }
    

    相关文章

      网友评论

          本文标题:Retrofit执行流程

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