Retrofit2.9.0版本主流程分析

Posted datian1234

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Retrofit2.9.0版本主流程分析相关的知识,希望对你有一定的参考价值。

简介

Retrofit turns your HTTP API into a Java interface.

Retrofit将HTTP API转换为Java接口

本文基于Retrofit2.9.0版本源码分析!

依赖添加:

com.squareup.retrofit2:retrofit:2.9.0

使用

我们在这以官网的Demo为例,来看下最简单的使用:

public interface GitHubService 
  @GET("users/user/repos")
  Call<List<Repo>> listRepos(@Path("user") String user);
 ①

Retrofit retrofit = new Retrofit.Builder()
    .baseUrl("https://api.github.com/")
    .build(); ②

GitHubService service = retrofit.create(GitHubService.class); ③

Call<List<Repo>> repos = service.listRepos("octocat"); ④

repos.enqueue() ⑤

总体流程分为四步:

  1. 创建一个接口,内部方法都是接口调用的方法,使用注解的方式添加请求类型、参数和回调数据等;
  2. 构建一个Retrofit对象,并且设置接口的baseUrl
  3. 使用retrofit.create(class)代理出一个我们第一步创建的接口实例;
  4. 使用接口实例执行具体的接口调用,返回Call对象;
  5. 使用call.enqueu()方法执行网络请求。

第一步不用具体分析,只需要知道如果使用注解来添加我们请求内容即可,具体如何解析这些注解会在第三步呈现出来,下面直接看第二步Retrofit的创建过程。

创建Retrofit

Retrofit.Builder().baseUrl(string)

retrofit2.Retrofit.Builder#baseUrl(java.lang.String)

public Builder baseUrl(String baseUrl) 
  Objects.requireNonNull(baseUrl, "baseUrl == null");
  return baseUrl(HttpUrl.get(baseUrl)); ①


public Builder baseUrl(HttpUrl baseUrl) 
  Objects.requireNonNull(baseUrl, "baseUrl == null");
  List<String> pathSegments = baseUrl.pathSegments();
  if (!"".equals(pathSegments.get(pathSegments.size() - 1)))  ②
    throw new IllegalArgumentException("baseUrl must end in /: " + baseUrl);
  
  this.baseUrl = baseUrl; ③
  return this;


Retrofit.Builder().baseUrl(string)一共做了三个操作:

  1. 将传入的url封装成HttpUrl对象;
  2. 判断url是否是以/结尾,不是的话直接抛出异常;
  3. HttpUrl赋值给Builder.baseUrl

Builder.build()

retrofit2.Retrofit.Builder#build

public Retrofit build() 
    // baseUrl不能为空
    if (baseUrl == null) 
      throw new IllegalStateException("Base URL required.");
     ①
    
    // 获取平台,Java/android
    Platform platform = Platform.get(); ②

    // 创建OkHttpClient对象
    okhttp3.Call.Factory callFactory = this.callFactory;
    if (callFactory == null) 
      callFactory = new OkHttpClient();
     ③

    // 创建回调线程池对象
    Executor callbackExecutor = this.callbackExecutor;
    if (callbackExecutor == null) 
      callbackExecutor = platform.defaultCallbackExecutor();
     ④

    // 创建适配器列表,并且添加默认的适配器
    List<CallAdapter.Factory> callAdapterFactories = new ArrayList<>(this.callAdapterFactories);
    List<? extends CallAdapter.Factory> defaultCallAdapterFactories =
        platform.createDefaultCallAdapterFactories(callbackExecutor);
    callAdapterFactories.addAll(defaultCallAdapterFactories); ⑤

    // 创建默认的转换器列表
    List<? extends Converter.Factory> defaultConverterFactories =
        platform.createDefaultConverterFactories();
    int defaultConverterFactoriesSize = defaultConverterFactories.size();
    List<Converter.Factory> converterFactories =
        new ArrayList<>(1 + this.converterFactories.size() + 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(defaultConverterFactories); ⑥

    // 创建Retrofit对象
    return new Retrofit(
        callFactory,
        baseUrl,
        unmodifiableList(converterFactories),
        defaultConverterFactoriesSize,
        unmodifiableList(callAdapterFactories),
        defaultCallAdapterFactories.size(),
        callbackExecutor,
        validateEagerly); ⑦
  


Builder.build()方法中主要就是创建或者获取一些重要的对象,一共包括6个对象,下面一个个分析下具体作用:

  1. 第一步判断baseUrl是否为空,为空直接抛异常;
  2. 第二步获取Platform平台对象,因为我们在Android工程中使用,所以获取的是Android21或者Android24其中一个,Platform定义了回调线程池、调用适配器和转换适配器对象等;
  3. 第三步获取回调线程池对象,会从Platform对象中获取默认的线程池;
  4. 第四步获取CallAdapter.Factory列表,并且添加从Platform中获取到的默认CallAdapter.Factory对象。CallAdapter的主要作用就是将我们接口返回的对象转换成想要的类型,典型的就是RxJavaCallAdapter,它就是将默认的Call转换成Observable
  5. 第五步获取Converter.Factory列表,同时也会从Platform中获取默认的Converter.Factory列表。Converter.Factory的主要作用就是将请求结果通过具体的操作转换成想要的类型,典型的就是GsonConverter,它就是将String转换成具体的数据类对象。
  6. 第六步创建Retrofit对象,然后设置上面获取的对象。

Retrofit.cerate()

retrofit2.Retrofit#create

public <T> T create(final Class<T> service) 
  validateServiceInterface(service);
  return (T)
      Proxy.newProxyInstance( ①
          service.getClassLoader(),
          new Class<?>[] service,
          new InvocationHandler() 
            private final Object[] emptyArgs = new Object[0];

            @Override
            public @Nullable Object invoke(Object proxy, Method method, @Nullable Object[] args)
                throws Throwable 
              // 判断Service是接口还是类,如果是类直接调用类的方法
              if (method.getDeclaringClass() == Object.class) 
                return method.invoke(this, args);
              
              args = args != null ? args : emptyArgs;
              Platform platform = Platform.get();
              return platform.isDefaultMethod(method)
                  ? platform.invokeDefaultMethod(method, service, proxy, args)
                  : loadServiceMethod(method).invoke(args); ②
            
          );


Retrofit.create(class)方法中可以看出主要的有两步:

  1. 第一步使用动态代理模式,根据传入的class对象代理最终代理出一个实例;
  2. 第二步先判断platform.isDefaultMethod(method),进入Android21类中此方法默认false,所以直接看loadServiceMethod(method)方法即可
    • loadServiceMethod(method)会创建一个ServiceMethod对象;
    • 再调用ServiceMethod.invoke(args)方法,这里传入的接口方法的参数

Retrofit.loadServiceMethod()

retrofit2.Retrofit#loadServiceMethod

ServiceMethod<?> loadServiceMethod(Method method) 
  // 查看是否命中缓存
  ServiceMethod<?> result = serviceMethodCache.get(method);
  if (result != null) return result;

  synchronized (serviceMethodCache) 
    // 加锁并且双重判断是否命中缓存
    result = serviceMethodCache.get(method);
    if (result == null) 
      // 获取新的ServiceMethod对象,并存入Map中
      result = ServiceMethod.parseAnnotations(this, method);
      serviceMethodCache.put(method, result);
    
  
  return result;


loadServiceMethod()方法内部逻辑还是比较简单,先是从Map中获取是否已经存在,不存在再加锁去获取新的ServiceMethod对象,最后放入缓存Map中。具体的获取流程还需要进入ServiceMethod.parseAnnotations(retrofit,method)方法中。

ServiceMethod.parseAnnotations()

retrofit2.ServiceMethod#parseAnnotations

static <T> ServiceMethod<T> parseAnnotations(Retrofit retrofit, Method method) 
  // 创建RequestFactory对象
  RequestFactory requestFactory = 
    RequestFactory.parseAnnotations(retrofit, method); ①
  
  // 获取方法返回类型
  Type returnType = method.getGenericReturnType();
  // 判断返回类型是否能够解析
  if (Utils.hasUnresolvableType(returnType)) 
    throw methodError(
        method,
        "Method return type must not include a type variable or wildcard: %s",
        returnType);
  
  // 返回类型不能为void类型
  if (returnType == void.class) 
    throw methodError(method, "Service methods cannot return void.");
   ②
  // 创建HttpServiceMethod对象
  return HttpServiceMethod.parseAnnotations(retrofit, method, requestFactory); ③


parseAnnotations()方法中主要做了三件事:

  1. 第一件就是创建了RequestFactory对象,这个接下来分析下这个对象作用是什么;
  2. 第二件通过Method获取方法返回值,并判断可用性;
  3. 第三件转到HttpServiceMethod中创建HttpServiceMethod对象,此类是ServiceMethod的子类。

RequestFactory.parseAnnotations(retrofit, method)

retrofit2.RequestFactory#parseAnnotations

static RequestFactory parseAnnotations(Retrofit retrofit, Method method) 
  return new Builder(retrofit, method).build();


Builder(Retrofit retrofit, Method method) 
  this.retrofit = retrofit;
  this.method = method;
  this.methodAnnotations = method.getAnnotations();
  this.parameterTypes = method.getGenericParameterTypes();
  this.parameterAnnotationsArray = method.getParameterAnnotations();


RequestFactory build() 
  for (Annotation annotation : methodAnnotations) 
    parseMethodAnnotation(annotation); ①
  
  // httpMethod不能为空,也就是设置的请求方式GET、POST等
  if (httpMethod == null) 
    throw methodError(method, "HTTP method annotation is required (e.g., @GET, @POST, etc.).");
   ②

  // 判断请求提是否合规
  if (!hasBody) 
    if (isMultipart) 
      throw methodError(
          method,
          "Multipart can only be specified on HTTP methods with request body (e.g., @POST).");
    
    if (isFormEncoded) 
      throw methodError(
          method,
          "FormUrlEncoded can only be specified on HTTP methods with "
              + "request body (e.g., @POST).");
    
   ③

  int parameterCount = parameterAnnotationsArray.length;
  parameterHandlers = new ParameterHandler<?>[parameterCount];
  for (int p = 0, lastParameter = parameterCount - 1; p < parameterCount; p++) 
    parameterHandlers[p] =
        parseParameter(p, parameterTypes[p], parameterAnnotationsArray[p], p == lastParameter);
   ④

  if (relativeUrl == null && !gotUrl) 
    throw methodError(method, "Missing either @%s URL or @Url parameter.", httpMethod);
  
  if (!isFormEncoded && !isMultipart && !hasBody && gotBody) 
    throw methodError(method, "Non-body HTTP method cannot contain @Body.");
  
  if (isFormEncoded && !gotField) 
    throw methodError(method, "Form-encoded method must contain at least one @Field.");
  
  if (isMultipart && !gotPart) 
    throw methodError(method, "Multipart method must contain at least one @Part.");
  

  return new RequestFactory(this); ⑤


parseAnnotations()方法直接调用了内部Builder.build()方法,build()方法中,可以细分为五步:

  1. 第一步通过parseMethodAnnotation()解析方法上注解,解析的内容包括:请求方式、请求头、请求地址、是否Multipart和是否FormUrlEncode等信息,下面会详细分析;
  2. 第二步判断请求方式,如果为空直接抛异常;
  3. 第三步判断MultipartFormUrlEncode注解,如果有请求体的时候,不可以有前面两个注解,否则直接抛异常;
  4. 第四步通过parseParameter解析参数上注解,包括BodyFiledHeaderQuery等信息;
  5. 第五步创建RequestFactory对象,将Builder传入进去。

RequestFactory.parseMethodAnnotation()

retrofit2.RequestFactory.Builder#parseMethodAnnotation

private void parseMethodAnnotation(Annotation annotation) 
  if (annotation instanceof DELETE) 
    parseHttpMethodAndPath("DELETE", ((DELETE) annotation).value(), false);
   else if (annotation instanceof GET) 
    parseHttpMethodAndPath("GET", ((GET) annotation).value(), false);
   else if (annotation instanceof HEAD) 
    parseHttpMethodAndPath("HEAD", ((HEAD) annotation).value(), false);
   else if (annotation instanceof PATCH) 
    parseHttpMethodAndPath("PATCH", ((PATCH) annotation).value(), true);
   else if (annotation instanceof POST) 
    parseHttpMethodAndPath("POST", ((POST) annotation).value(), true);
   else if (annotation instanceof PUT) 
    parseHttpMethodAndPath("PUT", ((PUT) annotation).value(), true);
   else if (annotation instanceof OPTIONS) 
    parseHttpMethodAndPath("OPTIONS", ((OPTIONS) annotation).value(), false);
   else if (annotation instanceof HTTP) 
    HTTP http = (HTTP) annotation;
    parseHttpMethodAndPath(http.method(), http.path(), http.hasBody());
   else if (annotation instanceof retrofit2.http.Headers) 
    String[] headersToParse = ((retrofit2.http.Headers) annotation).value();
    if (headersToParse.length == 0) 
      throw methodError(method, "@Headers annotation is empty.");
    
    headers = parseHeaders(headersToParse);
   else if (annotation instanceof Multipart) 
    if (isFormEncoded) 
      throw methodError(method, "Only one encoding annotation is allowed.");
    
    isMultipart = true;
   else if (annotation instanceof FormUrlEncoded) 
    if (isMultipart) 
      throw methodError(method, "Only one encoding annotation is allowed.");
    
    isFormEncoded = true;
  


parseMethodAnnotation()主要就是解析出方法上的注解,比如是GET还是POST请求,有没有额外添加HEADER,或者是不是MultipartFormUrlEncoded

RequestFactory.parseParameter()

retrofit2.RequestFactory.Builder#parseParameter

private @Nullable ParameterHandler<?> parseParameter(
    int p, Type parameterType, @Nullable Annotation[] annotations, boolean allowContinuation) 
  ParameterHandler<?> result = null;
  if (annotations != null) 
    for (Annotation annotation : annotations) 
      ParameterHandler<?> annotationAction =
          parseParameterAnnotation(p, parameterType, annotations, annotation);

      if (annotationAction == null) 
        continue;
      

      if (result != null) 
        throw parameterError(
            method, p, "Multiple Retrofit annotations found, only one allowed.");
      

      result = annotationAction;
    
  
.....
  return result;


parseParameter()具体的解析流程在parseParameterAnnotation()方法中,由于此方法源码过于长,此处就不再贴源码了,里面其实就是根据不同的注解类型来解析成对应的ParameterHandler对象。

具体的类型如下:

  • @Url注解,解析出来对应的是ParameterHandler.RelativeUrl()对象;
  • @Path注解,解析出来对应的是ParameterHandler.Path()对象;
  • @Query注解,解析出来对应的是ParameterHandler.Query()对象;
  • @QueryName注解,解析出来对应的是ParameterHandler.QueryName()对象;
  • @QueryMap注解,解析出来对应的是ParameterHandler.QueryMap()对象;
  • @Header注解,解析出来对应的是ParameterHandler.Header()对象;
  • @HeaderMap注解,解析出来对应的是ParameterHandler.HeaderMap()对象;
  • @Field注解,解析出来对应的是ParameterHandler.Field()对象;
  • @FieldMap注解,解析出来对应的是ParameterHandler.FieldMap()对象;
  • @Part注解,解析出来对应的是ParameterHandler.Part()对象;
  • @PartMap注解,解析出来对应的是ParameterHandler.PartMap()对象;
  • @Body注解,解析出来对应的是ParameterHandler.Body()对象;
  • @Tag注解,解析出来对应的是ParameterHandler.Tag()对象;

这就是所有的方法参数注解类型。

RequestFactory.parseAnnotations()分析完了之后回到HttpServiceMethod.parseAnnotations()

HttpServiceMethod.parseAnnotations()

retrofit2.HttpServiceMethod#parseAnnotations

static <ResponseT, ReturnT> HttpServiceMethod<ResponseT, ReturnT> parseAnnotations(
    Retrofit retrofit, Method method, RequestFactory requestFactory) 
  boolean isKotlinSuspendFunction = requestFactory.isKotlinSuspendFunction;
  boolean continuationWantsResponse = false;
  boolean continuationBodyNullable = false;
  boolean continuationIsUnit = false;

  Annotation[] annotations = method.getAnnotations();
  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 
      continuationIsUnit = Utils.isUnit(responseType);
    

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

  CallAdapter<ResponseT, ReturnT> callAdapter =
      createCallAdapter(retrofit, method, adapterType, annotations); ③
  Type responseType = callAdapter.responseType();
  if (responseType == okhttp3.Response.class) 
    throw methodError(
        method,
        "'"
            + getRawType(responseType).getName()
            + "' is not a valid response body type. Did you mean ResponseBody?");
  
  if (responseType == Response.class) 
    throw methodError(method, "Response must include generic type (e.g., Response<String>)");
  
  // TODO support Unit for Kotlin?
  if (requestFactory.httpMethod.equals("HEAD")
      && !Void.class.equals(responseType)
      && !Utils.isUnit(responseType)) 
    throw methodError(method, "HEAD method must use Void or Unit as response type.");
  

  Converter<ResponseBody, ResponseT> responseConverter =
      createResponseConverter(retrofit, method, responseType); ④

  okhttp3.Call.Factory callFactory = retrofit.callFactory; ⑤
  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,
            continuationIsUnit); ⑦
  


这里面的逻辑还是略微比较多的,逐一看下:

  1. 第一步,判断是否是Kotlin的挂起函数,然后通过getGenericParameterTypes获取方法的返回类型;
  2. 第二步,如果不是Kotlin的挂起函数,直接通过getGenericReturnType获取方法的返回类型,这里的返回类型如果是泛型的话有可能拿不到具体的泛型值;
  3. 第三步创建CallAdapter,这里假设我们没有设置任何额外的CallAdapter,会使用默认的DefaultCallAdapter对象;
  4. 第四步创建ConverterAdapter,这里我们一般使用Gson来解析响应结果,转换成数据类,这边假设使用的是GsonResponseBodyConverter对象;
  5. 第五步仅仅是获取Retrofit对象中callFactory
  6. 第六步和第七步对Kotlin的挂起函数做判断,分析过程中默认非挂起函数,直接进入第七步,烦恼会一个CallAdapted对象。

到这我们发现Retrofit.create()方法中,动态代理中loadServiceMethod()方法最终返回的就是CallAdapted对象,loadServiceMethod()方法后面直接调用了invoke()方法,接下来进入CallAdapted.invoke()方法。

CallAdapter.invoke()

进入CallAdapted对象中,发现并没有invoke()方法的实现,只能退而求其次去看它的父类了:

retrofit2.HttpServiceMethod#invoke  

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


invoke()方法中首先创建了一个OkHttpCall对象,然后调用adapt()方法。

OkhttpCallRetrofit用来管理发起网络调用和回调的具体类。

CallAdapted.adapt()

retrofit2.HttpServiceMethod.CallAdapted#adapt

@Override
protected ReturnT adapt(Call<ResponseT> call, Object[] args) 
  // 这里的callAdapter为DefaultCallAdapterFactory中CallAdapter
  return callAdapter.adapt(call);


retrofit2.DefaultCallAdapterFactory#get

return new CallAdapter<Object, Call<?>>() 
  @Override
  public Type responseType() 
    return responseType;
  

  @Override
  public Call<Object> adapt(Call<Object> call) 
    return executor == null ? call : new ExecutorCallbackCall<>(executor, call);
  
;

adapt()方法直接调用callAdapter.adapt()方法,前面我们说到,默认使用CallAdapter,它是有DefaultCallAdapterFactory创建而成,CallAdapter.adapt()方法中只是创建了一个ExecutorCallbackCall对象。

到这里我们就清除了,在使用章节第四步生成的Call其实就是ExecutorCallbackCall对象,让他调用它的enqueue()方法就可以发起网络请求。

ExecutorCallbackCall.enqueue()

retrofit2.DefaultCallAdapterFactory.ExecutorCallbackCall#enqueue

ExecutorCallbackCall(Executor callbackExecutor, Call<T> delegate) 
  this.callbackExecutor = callbackExecutor;
  this.delegate = delegate;


public void enqueue(final Callback<T> callback) 
  Objects.requireNonNull(callback, "callback == null");
  
  // 直接使用代理Call的enqueue方法,这里的delegate就是OkHttpCall对象
  delegate.enqueue(
      new Callback<T>() 
        @Override
        public void onResponse(Call<T> call, final Response<T> response) 
          // 主线程中回调结果,Android默认callbackExecutor为MainExecutor
          callbackExecutor.execute(
              () -> 
                if (delegate.isCanceled()) 
                  // Emulate OkHttp's behavior of throwing/delivering an IOException on
                  // cancellation.
                  callback.onFailure(ExecutorCallbackCall.this, new IOException("Canceled"));
                 else 
                  callback.onResponse(ExecutorCallbackCall.this, response);
                
              );
        

        @Override
        public void onFailure(Call<T> call, final Throwable t) 
          callbackExecutor.execute(() -> callback.onFailure(ExecutorCallbackCall.this, t));
        
      );


ExecutorCallbackCall.enqueue()方法很简单,直接调用delegate.enqueue(),然后将网络请求的结果回调到主线程中去处理。

这里的delegateCallAdapted.invoke()方法可以得知,它就是OkHttpCall对象,接着我们进入OkhttpCall.enqueue()方法。

OkHttpCall.enqueue()

retrofit2.OkHttpCall#enqueue

public void enqueue(final Callback<T> callback) 
  Objects.requireNonNull(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) 
        throwIfFatal(t);
        failure = creationFailure = t;
      
    
  

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

  if (canceled) 
    call.cancel();
  

  call.enqueue( ③
      new okhttp3.Callback() 
        @Override
        public void onResponse(okhttp3.Call call, okhttp3.Response rawResponse) 
          ...
        

        @Override
        public void onFailure(okhttp3.Call call, IOException e) 
          ...
        
      );


此方法才是最终调用Okhttp3发起网络请求最终地点,重要的一共有三步:

  1. 第一步检查rawCall是否为空;
  2. 第二步如果rawCall为空,需要通过createRawCall()来创建OKhttp3.Call对象;
  3. 使用Okhttp3.Call.enqueue()方法来发起异步请求。

到这为止,整个Retrofit网络请求流程就分析结束了,Retrofit并没有执行任何网络请求操作,只是将所有方法注解、参数注解解析好之后,交给Okhttp3来发起具体的网络请求。

超强干货来袭 云风专访:近40年码龄,通宵达旦的技术人生

以上是关于Retrofit2.9.0版本主流程分析的主要内容,如果未能解决你的问题,请参考以下文章

Android 12 版本 Data Call 移动数据业务流程分析

OKHttp分发器源码分析(两个版本)

OKHttp分发器源码分析(两个版本)

OKHttp分发器源码分析(两个版本)

uboot研读笔记 | 14 - uboot启动流程分析(2016.03版本)

Yii2 分析运行流程