美文网首页
Retrofit源码分析小结

Retrofit源码分析小结

作者: Dane_404 | 来源:发表于2019-03-19 23:17 被阅读0次

    1、从Retrofit retrofit = new Retrofit.Builder() .baseUrl(url).addConverterFactory(GsonConverterFactory.create()) .build()入手:

    public Retrofit build() {
        if (baseUrl == null) {
            throw new IllegalStateException("Base URL required.");  //baseUrl为null就抛异常
        }
    
        okhttp3.Call.Factory callFactory = this.callFactory;
        if (callFactory == null) {   //用户没用设置OK就创建默认的
            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就创建了,接下来看IpService ipService = retrofit.create(IpService.class),也就是create:

    public <T> T create(final Class<T> service) {
        Utils.validateServiceInterface(service);  //检查是不是接口,有没有继承接口,是不能继承其他接口的
        if (validateEagerly) {  //默认是false
        eagerlyValidateMethods(service);   //作用是将service所有方法加入缓存
        }
        //返回一个代理类,动态代理,Proxy.newProxyInstance是Android提供的
        return (T) Proxy.newProxyInstance(service.getClassLoader(), new Class<?>[] { service },
            new InvocationHandler() {
            private final Platform platform = Platform.get();
             //使用Retrofit当调用service的方法时调用,参数一是代理对象,二是调用的方法,三是参数
            @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);
            }
            });
    }
    

    所以调用任何方法,最后会走上面的invoke,那么看loadServiceMethod:

    ServiceMethod<?, ?> loadServiceMethod(Method method) {
        ServiceMethod<?, ?> result = serviceMethodCache.get(method); //有没缓存
        if (result != null) return result;
    
        synchronized (serviceMethodCache) {
        result = serviceMethodCache.get(method); //这里理解是保证线程安全
        if (result == null) {
            result = new ServiceMethod.Builder<>(this, method).build();  //将Method封装到ServiceMethod
            serviceMethodCache.put(method, result);
        }
        }
        return result;
    }
    

    看result = new ServiceMethod.Builder<>(this, method).build():

    public ServiceMethod build() {
        callAdapter = createCallAdapter();   //1,看下面的步骤
        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?");
        }
        responseConverter = createResponseConverter();
    
        for (Annotation annotation : methodAnnotations) {
            parseMethodAnnotation(annotation);    //解析请求方式,会对httpMethod 赋值
        }
    
        if (httpMethod == null) {
            throw methodError("HTTP method annotation is required (e.g., @GET, @POST, etc.).");
        }
    
        if (!hasBody) {
            if (isMultipart) {
            throw methodError(
                "Multipart can only be specified on HTTP methods with request body (e.g., @POST).");
            }
            if (isFormEncoded) {
            throw methodError("FormUrlEncoded can only be specified on HTTP methods with "
                + "request body (e.g., @POST).");
            }
        }
    
        int parameterCount = parameterAnnotationsArray.length;
        parameterHandlers = new ParameterHandler<?>[parameterCount];
        for (int p = 0; p < parameterCount; p++) {
            Type parameterType = parameterTypes[p];
            if (Utils.hasUnresolvableType(parameterType)) {
            throw parameterError(p, "Parameter type must not include a type variable or wildcard: %s",
                parameterType);
            }
    
            Annotation[] parameterAnnotations = parameterAnnotationsArray[p];
            if (parameterAnnotations == null) {
            throw parameterError(p, "No Retrofit annotation found.");
            }
    
            parameterHandlers[p] = parseParameter(p, parameterType, parameterAnnotations);
        }
    
        if (relativeUrl == null && !gotUrl) {
            throw methodError("Missing either @%s URL or @Url parameter.", httpMethod);
        }
        if (!isFormEncoded && !isMultipart && !hasBody && gotBody) {
            throw methodError("Non-body HTTP method cannot contain @Body.");
        }
        if (isFormEncoded && !gotField) {
            throw methodError("Form-encoded method must contain at least one @Field.");
        }
        if (isMultipart && !gotPart) {
            throw methodError("Multipart method must contain at least one @Part.");
        }
    
        return new ServiceMethod<>(this);
        }
    

    上面的注释1那里,createCallAdapter:

    private CallAdapter<T, R> createCallAdapter() {
      Type returnType = method.getGenericReturnType();  //获取返回值类型
      if (Utils.hasUnresolvableType(returnType)) {
        throw methodError(
            "Method return type must not include a type variable or wildcard: %s", returnType);
      }
      if (returnType == void.class) {
        throw methodError("Service methods cannot return void.");
      }
      Annotation[] annotations = method.getAnnotations();   //拿到方法的注解
      try {
        //noinspection unchecked
        //这里其实是ExecutorCallAdapterFactory内部的get方法,具有看下面
        return (CallAdapter<T, R>) retrofit.callAdapter(returnType, annotations); 
      } catch (RuntimeException e) { // Wide exception range because factories are user code.
        throw methodError(e, "Unable to create call adapter for %s", returnType);
      }
    }
    

    ExecutorCallAdapterFactory的get:

    @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;      //返回类型比如Call<MyData>,返回MyData
      }
    
      @Override public Call<Object> adapt(Call<Object> call) {
        return new ExecutorCallbackCall<>(callbackExecutor, call);  //将原本call的回调转发至UI线程
      }
    };
    }
    

    再回到Retrofit的create方法,最后走这一步serviceMethod.callAdapter.adapt(okHttpCall),上面分析知道其实是返回了ExecutorCallbackCall,看ExecutorCallbackCall的执行方法:

    @Override 
    public void enqueue(final Callback<T> callback) {
      checkNotNull(callback, "callback == null");
       //这里相当于OKHttp的newCall.enqueue
      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()) {
                //主线程回调,callback是在主线程创建的
                // 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);
            }
          });
        }
      });
    }
    

    最后总结下,retrofit通过Java的Proxy类完成动态代理的相关代理,拿到接口的实现类,在invoke方法内部,拿到我们所声明的注解以及实参等,构造ServiceMethod,ServiceMethod中解析了大量的信息,最后通过OKHttp请求,然后处理UI线程回调。

    相关文章

      网友评论

          本文标题:Retrofit源码分析小结

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