Retrofit源码分析小结

2019-03-19  本文已影响0人  Dane_404

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线程回调。

上一篇下一篇

猜你喜欢

热点阅读