解析Retrofit 原理

动态代理:

public static Object newProxyInstance(ClassLoader loader,Class<?>[] interfaces,InvocationHandler h)

调用一个接口的方法时,调用InvocationHandler的invoke(Object proxy, Method method, Object[] args)方法

Retrofit 主要的实现原理是动态代理,它的实现步骤主要有:

1.ServiceMethod解析接口方法上的注解,生成Okhttp.Request需要的参数;

2.生成OkHttpCall,作为okhttp3.Call的代理类;

3.CallAdapter把OkHttpCalll转换为Observable,生成responseObservable;

4.当responseObservable调用subscribe(observer)方法时 ,会调用OkHttpCall的方法,比如enqueue

5,OkHttpCall.enqueue的方法会调用ServiceMethod.toCall方法生成okhttp3.Call

6,用Okhttp请求网络,把请求结果放进observer返回去

public <T> T create(final Class<T> service) {
 
  return (T) Proxy.newProxyInstance(service.getClassLoader(), new Class<?>[] { service },
      new InvocationHandler() {
          ServiceMethod<Object, Object> serviceMethod =
              (ServiceMethod<Object, Object>) loadServiceMethod(method);
          OkHttpCall<Object> okHttpCall = new OkHttpCall<>(serviceMethod, args);
          return serviceMethod.adapt(okHttpCall);
        }
      });
}

1.ServiceMethod

因为ServiceMethod的主要功能是根据反射解析注解,比较消耗性能,所以会把ServiceMethod缓存,一个method对应一个ServiceMethod

ServiceMethod<?, ?> loadServiceMethod(Method method) {
//先从缓存中寻找ServiceMethod
  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;
}
public ServiceMethod build() {
  callAdapter = createCallAdapter();
  responseType = callAdapter.responseType();
 // 把返回值解析成Object
  responseConverter = createResponseConverter();
//解析方法的注解,比如get,pot,header
  for (Annotation annotation : methodAnnotations) {
    parseMethodAnnotation(annotation);
  }
//解析方法参数注解,比如path
  int parameterCount = parameterAnnotationsArray.length;
  parameterHandlers = new ParameterHandler<?>[parameterCount];
  for (int p = 0; p < parameterCount; p++) {
    Type parameterType = parameterTypes[p];
    Annotation[] parameterAnnotations = parameterAnnotationsArray[p];
 
    parameterHandlers[p] = parseParameter(p, parameterType, parameterAnnotations);
  }

  return new ServiceMethod<>(this);
}

2.OkHttpCall 和okHttp3.Call有相同的方法,比如调用OkHttpCall的enqueue方法最终执行的okhttp3.Call的enqueue方法,

okhttp3.Call对象是通过serviceMethod.toCall(args)方法创建,toCall方法会跟使用Okhttp创建call一样,先根据serviceMethod解析注解得到的参数生成Request,然后newCall。

3.CallAdapter的adapt方法,把OkHttpCall变成Observable返回,具体做法是生成一个持有OkHttpCall引用的Observable对象。

Observable<Response<R>> responseObservable = isAsync
    ? new CallEnqueueObservable<>(call)
    : new CallExecuteObservable<>(call);
会根据Observable<T> T的类型判断生成哪个Observable
if (isResult) {   //Observable<Result>
      observable = new ResultObservable<>(responseObservable);
    } else if (isBody) {  //Observable<R>
      observable = new BodyObservable<>(responseObservable);
    } else {   Observable<Response>
      observable = responseObservable;
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值