Retrofit源码流程分析

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/yangshuaionline/article/details/86540677

总体流程图:
在这里插入图片描述
先看一段代码:

Retrofit retrofit = new Retrofit.Builder()
	.baseUrl("http://10.0.2.2:8080")
	.addConverterFactory(GsonConverterFactory.create())
	.build();
APIInterface service = retrofit.create(APIInterface.class);
try {
	Call<ModelEntity> call = service.getEntity("aaa","123");
	call.enqueue(new Callback<ModelEntity>() {
		@Override
		public void onResponse(Call<ModelEntity> call, Response<ModelEntity> response) {
			ModelEntity entity = response.body();
			String result = entity.toString();
			Log.w("打印", "结果是"+result);
		}

		@Override
		public void onFailure(Call<ModelEntity> call, Throwable t) {
			Log.w("打印", "onFailure结果是"+t.toString());
		}
	});

}catch (Exception e){
	Log.w("打印", e.toString());
}

一、先看new Retrofit.Builder()的源码:

Builder(Platform platform) {
	this.platform = platform;
}

这句就是用来确定平台的,然后找到确定平台的代码:

private static Platform findPlatform() {
    try {
      Class.forName("android.os.Build");
      if (Build.VERSION.SDK_INT != 0) {
        return new Android();
      }
    } catch (ClassNotFoundException ignored) {
    }
    ...
    return new Platform();
  }

由于我用的是Android平台的,就只看Android相关代码了,不过这里用try catch来判断是不是Android平台我也挺惊讶的,至少之前看过的帖子都说不建议用try catch来判断。如果是Android平台,会返回一个Android对象。
这个过程就是初始化一个Android对象放倒Builder中。

看第二句:baseUrl(…)

public Builder baseUrl(String baseUrl) {
	...
	return baseUrl(HttpUrl.get(baseUrl));
}

这里调用okhttp的HttpUrl.get(String) 方法,生成了一个HttpUrl对象,然后该对象传给baseUrl方法。

public Builder baseUrl(HttpUrl baseUrl) {
      ...
      this.baseUrl = baseUrl;
      return this;
}

这个过程就是生成一个HttpUrl对象,然后放到Builder对象中。

第三步,添加转换器工厂:

public Builder addConverterFactory(Converter.Factory factory) {
	converterFactories.add(checkNotNull(factory, "factory == null"));
	return this;
}

这里添加是为了支持Gson格式,如果不添加的话,会爆出java.lang.IllegalArgumentException: Unable to create converter for class … for method …异常。

第四步,调用builder():

 public Retrofit build() {
      ...
      //配置okhttp
      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> callAdapterFactories = new ArrayList<>(this.callAdapterFactories);
      callAdapterFactories.addAll(platform.defaultCallAdapterFactories(callbackExecutor));

      // Make a defensive copy of the converters.
      List<Converter.Factory> converterFactories = new ArrayList<>(
          1 + this.converterFactories.size() + platform.defaultConverterFactoriesSize());

      // 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());
      converterFactories.addAll(this.converterFactories);
      converterFactories.addAll(platform.defaultConverterFactories());

      return new Retrofit(callFactory, baseUrl, unmodifiableList(converterFactories),
          unmodifiableList(callAdapterFactories), callbackExecutor, validateEagerly);
    }

callAdapterFactories、converterFactories、callbackExecutor、validateEagerly这几个对象暂时没看出来什么意思,暂时过,留到后边用到分析。
看Retrofit的构造方法:

Retrofit(okhttp3.Call.Factory callFactory, HttpUrl baseUrl,
      List<Converter.Factory> converterFactories, 
      List<CallAdapter.Factory> callAdapterFactories,
      @Nullable Executor callbackExecutor, 
      boolean validateEagerly) {
    this.callFactory = callFactory;
    this.baseUrl = baseUrl;
    this.converterFactories = converterFactories; // Copy+unmodifiable at call site.
    this.callAdapterFactories = callAdapterFactories; // Copy+unmodifiable at call site.
    this.callbackExecutor = callbackExecutor;
    this.validateEagerly = validateEagerly;
  }

到此,Retrofit初始化完成。

五、初始化APIInterface

 public <T> T create(final Class<T> service) {
    ...
    if (validateEagerly) {
    //解析接口中的方法(这里知识做异常判断)
      eagerlyValidateMethods(service);
    }
    //根据反射生成接口实现类
    return (T) Proxy.newProxyInstance(service.getClassLoader(), new Class<?>[] { service },
        new InvocationHandler() {
          private final Platform platform = Platform.get();
          private final Object[] emptyArgs = new Object[0];

          @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);
            }
            return loadServiceMethod(method).invoke(args != null ? args : emptyArgs);
          }
        });
  }

通过反射,依据接口生成请求实体,然后调用接口中方法,返回Call对象,然后调用enqueue方法处理回调。

六、处理回调:

Call<ModelEntity> call = service.getEntity("aaa","123");
call.enqueue(new Callback<ModelEntity>() {
	@Override
	public void onResponse(Call<ModelEntity> call, Response<ModelEntity> response) {
		ModelEntity entity = response.body();
		String result = entity.toString();
		Log.w("打印", "结果是"+result);
	}
	@Override
	public void onFailure(Call<ModelEntity> call, Throwable t) {
		Log.w("打印", "onFailure结果是"+t.toString());
	}
});

前面通过反射生成请求对象了之后,直接调用对象中的方法发出请求,然后onResponse中处理请求回调。

七、反射的流程

重点看如代码:

return (T) Proxy.newProxyInstance(service.getClassLoader(), new Class<?>[] { service },
        new InvocationHandler() {
	...
	@Override public Object invoke(Object proxy, Method method, @Nullable Object[] args)
            throws Throwable {
		...
		return loadServiceMethod(method).invoke(args != null ? args : emptyArgs);
	}
});

然后关联到loadServiceMethod方法中:

private final Map<Method, ServiceMethod<?>> serviceMethodCache = new ConcurrentHashMap<>();
ServiceMethod<?> loadServiceMethod(Method method) {
    ...
    synchronized (serviceMethodCache) {
      result = serviceMethodCache.get(method);
      if (result == null) {
        result = ServiceMethod.parseAnnotations(this, method);
        ...
      }
    }
    return result;
  }

然后关联到ServiceMethod.parseAnnotations(this, method);方法中

static <T> ServiceMethod<T> parseAnnotations(Retrofit retrofit, Method method) {
	//	处理方法注释,配置请求类型和入参,返回一个请求对象。
    RequestFactory requestFactory = RequestFactory.parseAnnotations(retrofit, method);
    //	方法的返回类型
    Type returnType = method.getGenericReturnType();
    ...
    //	将接口的调用转为Http调用
    return HttpServiceMethod.parseAnnotations(retrofit, method, requestFactory);
  }

配置网络请求

RequestFactory build() {
	  //遍历方法注解,确定请求类型。
      for (Annotation annotation : methodAnnotations) {
        parseMethodAnnotation(annotation);
      }
      ...
      //根据方法参数注解,入参。
      int parameterCount = parameterAnnotationsArray.length;
      parameterHandlers = new ParameterHandler<?>[parameterCount];
      for (int p = 0; p < parameterCount; p++) {
        parameterHandlers[p] = parseParameter(p, parameterTypes[p], parameterAnnotationsArray[p]);
      }
	  ...
	  //返回一个请求对象。
      return new RequestFactory(this);
    }
static <ResponseT, ReturnT> HttpServiceMethod<ResponseT, ReturnT> parseAnnotations(
      Retrofit retrofit, Method method, RequestFactory requestFactory) {
     //前面没有添加addCallAdapterFactory,暂时不考虑此属性。
    CallAdapter<ResponseT, ReturnT> callAdapter = createCallAdapter(retrofit, method);
    Type responseType = callAdapter.responseType();
    ...
    Converter<ResponseBody, ResponseT> responseConverter =
        createResponseConverter(retrofit, method, responseType);
	//调用之前(第四步)初始化配置的网络请求
    okhttp3.Call.Factory callFactory = retrofit.callFactory;
    return new HttpServiceMethod<>(requestFactory, callFactory, callAdapter, responseConverter);
  }

返回了一个持有requestFactory, callFactory, callAdapter, responseConverter的HttpServiceMethod,然后再调用invoke方法返回请求实体。然后返回到第五步中,成功返回请求对象。

猜你喜欢

转载自blog.csdn.net/yangshuaionline/article/details/86540677