Retrofit2.3源码分析

声明:通过Retrofit的使用步骤来对Retrofit的源码进行解读;
1、基本使用方法:
第一步添加依赖库(app的build.gradle下):
dependencies{
	    implementation 'com.squareup.retrofit2:retrofit:2.3.0'//Retrofit的库
		implementation 'com.squareup.retrofit2:converter-gson:2.3.0'//需要使用到的Gson转化库
		implementation 'com.squareup.retrofit2:adapter-rxjava2:2.3.0'//需要使用的Rxjava库
		implementation 'io.reactivex.rxjava2:rxandroid:2.0.1'//线程切换的库
	}
第二步实际使用:
Retrofit.Builder builder = new Retrofit.Builder();
        mRetrofit = builder.baseUrl(AppNetConfig.BASE)
                .client(genericClient())
                .addConverterFactory(GsonConverterFactory.create())
                .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
                .build();
		mRetrofit.create(ApiService.class);
		//Retrofit的特殊之处,使用接口对网络请求进行配置,实现解耦功能,这也是这个库流行的根本原因
		//接口的声明具体使用方法参考Retrofit的官方介绍
public interface ApiService {     //示例
	@GET(AppNetConfig.HOME_ENTERPRISE)
	Observable<HomeEnterpriseBean> getHomeEnterprise();
}		
*genericClient()为产生OkHttpClient的方法,以下仅供参考*
		public OkHttpClient genericClient() {
			long SIZE_OF_CACHE = 10 * 1024 * 1024; // 10 MiB
			String cacheFile = EnterpriseInfoQuery.mContext.getCacheDir() + "/http";
			Cache cache = new Cache(new File(cacheFile), SIZE_OF_CACHE);
			OkHttpClient.Builder builder = new OkHttpClient.Builder();
			//HttpsUtils采用的张鸿洋的OkHttpUtils中的类
			HttpsUtils.SSLParams sslSocketFactory = HttpsUtils.getSslSocketFactory(null, null, null);
			return builder.connectTimeout(20000L, TimeUnit.MILLISECONDS)
                .readTimeout(20000L, TimeUnit.MILLISECONDS)
                .hostnameVerifier(new HostnameVerifier() {
                    @Override
                    public boolean verify(String hostname, SSLSession session) {
                        return true;
                    }
                })
                .addNetworkInterceptor(new Interceptor() {
                    @Override
                    public Response intercept(Chain chain) throws IOException {
                        return chain.proceed(chain.request()
                                .newBuilder()
                                .addHeader("Authorization", token)
                                .addHeader("Content-Type", "application/json;charset=-8")
                                .addHeader("xxx","xxxxxx")//为头部添加自定义字段
                                .build());
                    }
                })
				//添加缓存配合使用,并且需要在头部声明max-age属性
//                .addNetworkInterceptor(CachingControlInterceptor.REWRITE_RESPONSE_INTERCEPTOR)
//                .addInterceptor(CachingControlInterceptor.REWRITE_RESPONSE_INTERCEPTOR_OFFLINE)
				//支持访问Https形式的网址,但是未提供证书校验(与Http仅一个"s"字符的区别,其他没有区别)
                .sslSocketFactory(sslSocketFactory.sSLSocketFactory, sslSocketFactory.trustManager)
                .cache(cache)
                .build();
		}

2、步骤分解:

Retrofit.Builder():

Builder(Platform platform) {
      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());//简译:添加转化工厂保证使用responseBody时正常
    }
    public Builder() {
      this(Platform.get());//get()->findPlatform()最终指向为Android平台
    }
	
	
	class Platform {
		private static final Platform PLATFORM = findPlatform();

		static Platform get() {
		return PLATFORM;
	}

	private static Platform findPlatform() {
		try {
			Class.forName("android.os.Build");
			if (Build.VERSION.SDK_INT != 0) {
			return new Android();
			}
		} catch (ClassNotFoundException ignored) {
		}
		try {
			Class.forName("java.util.Optional");
			return new Java8();
		} catch (ClassNotFoundException ignored) {
		}
		return new Platform();
	}
	//Android平台(默认回调在主线程执行)
	static class Android extends Platform {
		@Override public Executor defaultCallbackExecutor() {
			return new MainThreadExecutor();
		}

		@Override CallAdapter.Factory defaultCallAdapterFactory(@Nullable Executor callbackExecutor) {
			if (callbackExecutor == null) throw new AssertionError();
			return new ExecutorCallAdapterFactory(callbackExecutor);
		}

		static class MainThreadExecutor implements Executor {
			private final Handler handler = new Handler(Looper.getMainLooper());

			@Override public void execute(Runnable r) {
			handler.post(r);
			}
		}
	}

builder.baseUrl(AppNetConfig.BASE):转入根地址

public Builder baseUrl(String baseUrl) {
	//非空检查
      checkNotNull(baseUrl, "baseUrl == null");
	  //将地址转化为HttpUrl的格式
      HttpUrl httpUrl = HttpUrl.parse(baseUrl);
      if (httpUrl == null) {
        throw new IllegalArgumentException("Illegal URL: " + baseUrl);
      }
      return baseUrl(httpUrl);
    }
.client(genericClient()):初始化OkHttpClient(使用的网络请求是OkHttp3)
	public Builder client(OkHttpClient client) {
      return callFactory(checkNotNull(client, "client == null"));
    }
	public Builder callFactory(okhttp3.Call.Factory factory) {
      this.callFactory = checkNotNull(factory, "factory == null");
      return this;//*return this;这种写法是Build设计模式的核心
    }
.addConverterFactory(GsonConverterFactory.create()):添加转化工厂(可自定义),通用性操作,

包括将发送的字符放到对象里然后通过Gson工厂转为json串(这地方略显繁琐,但是对kotlin而言是方便的)

public Builder addConverterFactory(Converter.Factory factory) {
      converterFactories.add(checkNotNull(factory, "factory == null"));
      return this;
    }
.addCallAdapterFactory(RxJava2CallAdapterFactory.create()):添加回调,后面会设计同步,异步,很重要的步骤
	public static RxJava2CallAdapterFactory create() {
		return new RxJava2CallAdapterFactory(null, false);
    }
	@Override
  public CallAdapter<?, ?> get(Type returnType, Annotation[] annotations, Retrofit retrofit) {
    Class<?> rawType = getRawType(returnType);

    if (rawType == Completable.class) {
      // Completable is not parameterized (which is what the rest of this method deals with) so it
      // can only be created with a single configuration.
      return new RxJava2CallAdapter(Void.class, scheduler, isAsync, false, true, false, false,
          false, true);
    }

    ......

    return new RxJava2CallAdapter(responseType, scheduler, isAsync, isResult, isBody, isFlowable,
        isSingle, isMaybe, false);
  }
  /*这个get()很重要后面会用到*/
.build():参数检查及设置默认初始化参数
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);
    }
	/*注意:这个类的另外三个方法后面会用到:callAdapter、requestBodyConverter、responseBodyConverter。
			这里callAdapter为获取adapterFactoties中添加的实例、其他两个方法类似*/
	public CallAdapter<?, ?> callAdapter(Type returnType, Annotation[] annotations) {
		return nextCallAdapter(null, returnType, annotations);
	}

	/**
	* Returns the {@link CallAdapter} for {@code returnType} from the available {@linkplain
	* #callAdapterFactories() factories} except {@code skipPast}.
	*
	* @throws IllegalArgumentException if no call adapter available for {@code type}.
	*/
	public CallAdapter<?, ?> nextCallAdapter(@Nullable 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) {
				return adapter;
			}
		}
		......省略异常日志输出
	}
上面都是一些前期的参数准备工作,下面开始核心内容:
mRetrofit.create(ApiService.class)://创建Api接口,就是将定义好的接口声明传给Retrofit,Retrofit使用代理对ApiService进行解析
 public <T> T create(final Class<T> service) {
    Utils.validateServiceInterface(service);//检测是否是接口、是否是单一接口
    if (validateEagerly) {//先行检查
      eagerlyValidateMethods(service);//--->loadServiceMethod(method);
    }
    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以OkHttp3为基础的网络请求*/
            OkHttpCall<Object> okHttpCall = new OkHttpCall<>(serviceMethod, args);
			/*这个adapter方法最终指向了RxJava2CallAdapter*/
            return serviceMethod.callAdapter.adapt(okHttpCall);
          }
        });
  }
	
	--------------------------------------------------
	这里的服务方法使用缓存的模式进行加载避免了重复解析,提升了很大的效率。
	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();
				//将解析的方法放入缓存中
				serviceMethodCache.put(method, result);
			}
		}
		return result;
	}
	在ServiceMethod中
	public ServiceMethod build() {
	  /*获取callAdapter*/
      callAdapter = createCallAdapter();
	  
      responseType = callAdapter.responseType();
	  
      ......
	  /*返回数据转化器*/
      responseConverter = createResponseConverter();

	  /*这个就是对已声明的ApiService注解分析(包括使用的Http(s)协议头部和路径)*/
      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, parameterType, parameterAnnotations);
      }
      ......

      return new ServiceMethod<>(this);
    }
	
	private CallAdapter<T, R> createCallAdapter() {
      ......
      try {
        //noinspection unchecked
		/*调用到Retrofit类中的callAdapter(前面有提到RxJava2CallAdapterFactory),最终获取的是RxJava2CallAdapter的实例*/
        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);
      }
    }
	
	private Converter<ResponseBody, T> createResponseConverter() {
      Annotation[] annotations = method.getAnnotations();
      try {
		/*Retrofit中的返回体转化器,指向的是Gson(自定义的则指向自定义)*/
        return retrofit.responseBodyConverter(responseType, annotations);
      } catch (RuntimeException e) { // Wide exception range because factories are user code.
        throw methodError(e, "Unable to create converter for %s", responseType);
      }
    }
	--------------------------------------------------
	在OkHttpCall中的两个重要方法(enqueue异步执行方法,execute同步网络请求方法,核心createRawCall)
	
@Override public void enqueue(final Callback<T> callback) {
    checkNotNull(callback, "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;
        }
      }
    }

	......

    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 Response<T> execute() throws IOException {
    okhttp3.Call call;

    synchronized (this) {
	  ......
      call = rawCall;
      if (call == null) {
        try {
          call = rawCall = createRawCall();
        } catch (IOException | RuntimeException e) {
          creationFailure = e;
          throw e;
        }
      }
    }
	......
    return parseResponse(call.execute());
  }
	
  private okhttp3.Call createRawCall() throws IOException {
	//将参数转化为请求
    Request request = serviceMethod.toRequest(args);
	//新建OkHttp3为基础的网络请求---->RxJava2CallAdapter中*/
    okhttp3.Call call = serviceMethod.callFactory.newCall(request);
    if (call == null) {
      throw new NullPointerException("Call.Factory returned null.");
    }
    return call;
  }
	
	-----------------------------------------------------------
	RxJava2CallAdapter中的同步异步请求,接入RxJava2的流式编程
	 @Override public Object adapt(Call<R> call) {
	 /*并将结果返回为Observable*/
    Observable<Response<R>> responseObservable = isAsync
        ? new CallEnqueueObservable<>(call)
        : new CallExecuteObservable<>(call);
	
    Observable<?> observable;
    if (isResult) {
      observable = new ResultObservable<>(responseObservable);
    } else if (isBody) {
      observable = new BodyObservable<>(responseObservable);
    } else {
      observable = responseObservable;
    }

    ......
    return observable;
  }
  
		CallEnqueueObservable中的核心步骤call.enqueue(callback)
		@Override protected void subscribeActual(Observer<? super Response<T>> observer) {
		// Since Call is a one-shot type, clone it for each new observer.
			Call<T> call = originalCall.clone();
			CallCallback<T> callback = new CallCallback<>(call, observer);
			observer.onSubscribe(callback);
			call.enqueue(callback);
		}
		CallExecuteObservable中核心步骤call.execute()
		@Override protected void subscribeActual(Observer<? super Response<T>> observer) {
			// Since Call is a one-shot type, clone it for each new observer.
			Call<T> call = originalCall.clone();
			observer.onSubscribe(new CallDisposable(call));

			boolean terminated = false;
			try {
			Response<T> response = call.execute();
			......
			}
		}
	parseResponse方法是很重要的一环,将call返回的Response通过Gson转化为对象
Response<T> parseResponse(okhttp3.Response rawResponse) throws IOException {
    ResponseBody rawBody = rawResponse.body();

    // Remove the body's source (the only stateful object) so we can pass the response along.
    rawResponse = rawResponse.newBuilder()
        .body(new NoContentResponseBody(rawBody.contentType(), rawBody.contentLength()))
        .build();

	......
    try {
      T body = serviceMethod.toResponse(catchingBody);
      return Response.success(body, rawResponse);
	......
	}
	ServiceMethod中
	R toResponse(ResponseBody body) throws IOException {
		return responseConverter.convert(body);
	}
	GsonResponseBodyConverter中有,Retrofit中提到responseBodyConverter的最终指向
	@Override public T convert(ResponseBody value) throws IOException {
		JsonReader jsonReader = gson.newJsonReader(value.charStream());
		try {
			return adapter.read(jsonReader);
		} finally {
			value.close();
		}
	}
至此真正的网络请求发起并获取对应的response传入Observable中



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值