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

相关推荐
烬奇小云3 小时前
认识一下Unicorn
android·python·安全·系统安全
顾北川_野15 小时前
Android 进入浏览器下载应用,下载的是bin文件无法安装,应为apk文件
android
CYRUS STUDIO15 小时前
Android 下内联汇编,Android Studio 汇编开发
android·汇编·arm开发·android studio·arm
右手吉他15 小时前
Android ANR分析总结
android
PenguinLetsGo17 小时前
关于 Android15 GKI2407R40 导致梆梆加固软件崩溃
android·linux
杨武博19 小时前
音频格式转换
android·音视频
音视频牛哥21 小时前
Android音视频直播低延迟探究之:WLAN低延迟模式
android·音视频·实时音视频·大牛直播sdk·rtsp播放器·rtmp播放器·android rtmp
ChangYan.1 天前
CondaError: Run ‘conda init‘ before ‘conda activate‘解决办法
android·conda
二流小码农1 天前
鸿蒙开发:ForEach中为什么键值生成函数很重要
android·ios·harmonyos
夏非夏1 天前
Android 生成并加载PDF文件
android