Android Retrofit原理浅析

官方地址:Retrofit

原理:Retrofit 本质上是代理了OKhttp,使用代理模式,Type-Safe 类型安全 编译器把类型检查出 避免类型错误,

enqueue 异步 切换线程

execute 同步 不切换线程

enqueue:Call接口定义的抽象方法

Retrofit.Create() 方法首先验证接口validateServiceInterface(Class <T> service)

  public <T> T create(final Class<T> service) {
//验证接口
    validateServiceInterface(service);

//动态代理 运行时创建
//getClassLoader classLoad 临时的ClassLoad
//new Class<?>[] { service } service 当前的interface 
    return (T) Proxy.newProxyInstance(service.getClassLoader(), new Class<?>[] { service },
 //实际代理匿名对象
 new InvocationHandler() {
          private final Platform platform = Platform.get();
          private final Object[] emptyArgs = new Object[0];

//核心方法  invoke 
          @Override public @Nullable Object invoke(Object proxy, Method method,
              @Nullable Object[] args) throws Throwable {
            // If the method is a method from Object then defer to normal invocation.

//确保是声明在接口里的方法(当前service  interface )而不是Object里的 如果是Object的方法 比如 toString  就调用这一行
            if (method.getDeclaringClass() == Object.class) {
              return method.invoke(this, args);
            }
//如果是JAVA8的默认方法 就执行
//platform 兼容类 可以兼容一些旧平台做默认处理 
// 比如platform 里的 isDefaultMethod 方法 会判断java8 hasJava8Types
            if (platform.isDefaultMethod(method)) {
              return platform.invokeDefaultMethod(method, service, proxy, args);
            }

//通过loadMethod方法进行反射调用
            return loadServiceMethod(method).invoke(args != null ? args : emptyArgs);
          }
        });
  }

ServiceMethod<?> loadServiceMethod(Method method) {
//从缓存中读取
//serviceMethodCache 是一个Map ,用Map做缓存
    ServiceMethod<?> result = serviceMethodCache.get(method);
    if (result != null) return result;

    synchronized (serviceMethodCache) {
      result = serviceMethodCache.get(method);
      if (result == null) {
//核心方法
        result = ServiceMethod.parseAnnotations(this, method);
        serviceMethodCache.put(method, result);
      }
    }
    return result;
  }

HttpServiceMethod

 @Override final @Nullable ReturnT invoke(Object[] args) {
    Call<ResponseT> call = new OkHttpCall<>(requestFactory, args, callFactory, responseConverter);
    return adapt(call, args);
  }


 Type adapterType;
    if (isKotlinSuspendFunction) {
      Type[] parameterTypes = method.getGenericParameterTypes();
      Type responseType = Utils.getParameterLowerBound(0,
          (ParameterizedType) parameterTypes[parameterTypes.length - 1]);
      if (getRawType(responseType) == Response.class && responseType instanceof ParameterizedType) {
        // Unwrap the actual body type from Response<T>.
        responseType = Utils.getParameterUpperBound(0, (ParameterizedType) responseType);
        continuationWantsResponse = true;
      } else {
        // TODO figure out if type is nullable or not
        // Metadata metadata = method.getDeclaringClass().getAnnotation(Metadata.class)
        // Find the entry for method
        // Determine if return type is nullable or not
      }

      adapterType = new Utils.ParameterizedTypeImpl(null, Call.class, responseType);
      annotations = SkipCallbackExecutorImpl.ensurePresent(annotations);
    } else {
      adapterType = method.getGenericReturnType();
    }

 okhttp3.Call.Factory callFactory = retrofit.callFactory;

//是否是kotlin挂起 的方法所生成的  关键字 susped
    if (!isKotlinSuspendFunction) {
      return new CallAdapted<>(requestFactory, callFactory, responseConverter, callAdapter);
    } else if (continuationWantsResponse) {
      //noinspection unchecked Kotlin compiler guarantees ReturnT to be Object.
      return (HttpServiceMethod<ResponseT, ReturnT>) new SuspendForResponse<>(requestFactory,
          callFactory, responseConverter, (CallAdapter<ResponseT, Call<ResponseT>>) callAdapter);
    } else {
      //noinspection unchecked Kotlin compiler guarantees ReturnT to be Object.
      return (HttpServiceMethod<ResponseT, ReturnT>) new SuspendForBody<>(requestFactory,
          callFactory, responseConverter, (CallAdapter<ResponseT, Call<ResponseT>>) callAdapter,
          continuationBodyNullable);
    }


OkhttpCall 
OkHttpCall<T> implements Call<T>

  @Override public void enqueue(final Callback<T> callback) {
//空值判断
    Objects.requireNonNull(callback, "callback == null");

    okhttp3.Call call; //call  
//    okhttp3.Call call = callFactory.newCall(requestFactory.create(args)); 通过工厂模式创建

    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) {
          throwIfFatal(t);
          failure = creationFailure = t;
        }
      }
    }

    if (failure != null) {
      callback.onFailure(this, failure);
      return;
    }

    if (canceled) {
      call.cancel();
    }

//okhttp enqueue 执行
    call.enqueue(new okhttp3.Callback() {
      @Override public void onResponse(okhttp3.Call call, okhttp3.Response rawResponse) {
        Response<T> response;
        try {
//解析数据 
          response = parseResponse(rawResponse);
        } catch (Throwable e) {
          throwIfFatal(e);
          callFailure(e);
          return;
        }

        try {
//解析成功
          callback.onResponse(OkHttpCall.this, response);
        } catch (Throwable t) {
          throwIfFatal(t);
          t.printStackTrace(); // TODO this is not great
        }
      }

      @Override public void onFailure(okhttp3.Call call, IOException e) {
//解析失败
        callFailure(e);
      }

      private void callFailure(Throwable e) {
        try {
          callback.onFailure(OkHttpCall.this, e);
        } catch (Throwable t) {
          throwIfFatal(t);
          t.printStackTrace(); // TODO this is not great
        }
      }
    });
  }

一系列验证

private void validateServiceInterface(Class<?> service) {
    if (!service.isInterface()) {
//验证是不是传入的一个Interface 不是的话就抛异常
      throw new IllegalArgumentException("API declarations must be interfaces.");
    }

//创建一个双向队列 
    Deque<Class<?>> check = new ArrayDeque<>(1);
//添加当前service 
    check.add(service);
    while (!check.isEmpty()) {
//移除上一个添加的  然后读取后面的
      Class<?> candidate = check.removeFirst();

      if (candidate.getTypeParameters().length != 0) {
//判断不能是泛型接口  <T>   是泛型接口 抛出异常
        StringBuilder message = new StringBuilder("Type parameters are unsupported on ")
            .append(candidate.getName());
        if (candidate != service) {
          message.append(" which is an interface of ")
              .append(service.getName());
        }
        throw new IllegalArgumentException(message.toString());
      }
      Collections.addAll(check, candidate.getInterfaces());
    }

//进一步验证  validateEagerly 验证flag
    if (validateEagerly) {
      Platform platform = Platform.get();
      for (Method method : service.getDeclaredMethods()) {
//判断是否是默认方法和静态方法 
//防止java8有默认实现方法和静态的方法
        if (!platform.isDefaultMethod(method) && !Modifier.isStatic(method.getModifiers())) {

//Retrofit 接口第一次被调用的时候 会有一些初始化操作 包括验证
          loadServiceMethod(method);
        }
      }
    }
  }


 ServiceMethod<?> loadServiceMethod(Method method) {
    ServiceMethod<?> result = serviceMethodCache.get(method);
    if (result != null) return result;

    synchronized (serviceMethodCache) {
      result = serviceMethodCache.get(method);
      if (result == null) {
        result = ServiceMethod.parseAnnotations(this, method);
        serviceMethodCache.put(method, result);
      }
    }
    return result;
  }

adapt 包装盒适配了OkHttpCall 异步切换线程以及适配RxJava,

通过包装CallAdapter,内部通过CallBackExecutor实现

然后由Executor 线程池 的CallBack进行同步操作 execute

通过ExecutorCallBackCall 置换OkHttpCall

会涉及到PlatForm的DefaultCallBackExecutor 创建MainThreadExecutor 然后执行Runable

OkHttpCall 创建过程

RequestFactory.parseAnnotions 通过Build, 通过parseMethodAnnotions 分析注解 枚举 比如GET / POST /DELETE / PUT等 对请求方法进行记录 分析 以及注解 参数类型 和 返回类型 进行判断进行拼接 然后通过ReequestFastory创建OkHttp3的Request

解析结果 parseRespose,通过ReseponseConverter.convert对数据 进行解析,在OKHTTPCall创建的时候创建出来

GsonCOnverterFastory 解析 通过conver方法 然后通过JsonReader

相关推荐
Dnelic-1 小时前
【单元测试】【Android】JUnit 4 和 JUnit 5 的差异记录
android·junit·单元测试·android studio·自学笔记
Eastsea.Chen3 小时前
MTK Android12 user版本MtkLogger
android·framework
长亭外的少年11 小时前
Kotlin 编译失败问题及解决方案:从守护进程到 Gradle 配置
android·开发语言·kotlin
建群新人小猿13 小时前
会员等级经验问题
android·开发语言·前端·javascript·php
1024小神14 小时前
tauri2.0版本开发苹果ios和安卓android应用,环境搭建和最后编译为apk
android·ios·tauri
兰琛14 小时前
20241121 android中树结构列表(使用recyclerView实现)
android·gitee
Y多了个想法15 小时前
RK3568 android11 适配敦泰触摸屏 FocalTech-ft5526
android·rk3568·触摸屏·tp·敦泰·focaltech·ft5526
NotesChapter16 小时前
Android吸顶效果,并有着ViewPager左右切换
android
_祝你今天愉快17 小时前
分析android :The binary version of its metadata is 1.8.0, expected version is 1.5.
android
暮志未晚Webgl18 小时前
109. UE5 GAS RPG 实现检查点的存档功能
android·java·ue5