Android Retrofit source code reading notes (4)

Retrofit source code reading notes (4)

The first article introduces Retrofitdynamic proxy implementation, method annotation analysis, etc.: Android Retrofit source code reading notes (1) .
The second article introduces Retrofithow to parse the parameters in the method : Android Retrofit source code reading notes (2) .
The third article introduces Retrofithow to build Httpthe request task: Android Retrofit source code reading notes (3) .

This article is the fourth in a series of articles. Logically speaking, the previous articles have already Retrofitrun through the entire process. There should be nothing more to say in the follow-up. However, Retrofitthere are still two advanced usages in use, that is, automatic Definition CallAdapterFactoryand ConverterFactory, I will assume that readers have read my previous articles and will not explain these two classes any more. This article will use the source code analysis of Retrofitthe officially defined RxJava3CallAdapterFactoryand MoshiConverterFactoryto help everyone better understand how to customize them. Define a CallAdapterFactoryand ConverterFactory. Get ready to go.

RxJava3CallAdapterFactory

By default, everyone is familiar with it RxJava. Students who are not familiar with it can go to the Internet to find information and learn it. I will not introduce it separately here. RxJava3CallAdapterFactoryThere are three ways to create: RxJava3CallAdapterFactory#create(), RxJava3CallAdapterFactory#createSynchronous()and RxJava3CallAdapterFactory#createWithScheduler().

  • create()
    Create OkHttpan asynchronous request RxJava3CallAdapterFactory, and the final request is in OkHttpthe Dispatcherthread pool.

  • createSynchronous()
    Create OkHttpa synchronous request RxJava3CallAdapterFactory, and the final request thread is RxJavadetermined by.

  • createWithScheduler()
    When creating OkHttpa synchronous request RxJava3CallAdapterFactory, the final request thread is determined by the passed Scheduler.

As mentioned in the previous article, the usable ones Retrofitwill CallAdatperFactory#get()be obtained according to the method CallAdapter, and CallAdatperFactorythe main judgment basis is to judge whether the current supports this type through adatperType( ) . If it does not support it, it will return empty directly, and it will try to get it from other Continue to search in . Create a corresponding return if supported.returnTypeCallAdapterFactoryRetrofitCallAdapterFactoryCallAdapter

Monkey, let’s take a look at the implementation of today’s first method RxJava3CallAdapterFactory#get():

  @Override
  public @Nullable CallAdapter<?, ?> get(
      Type returnType, Annotation[] annotations, Retrofit retrofit) {
    
    
    Class<?> rawType = getRawType(returnType);
    
    // 如果 `adapterType` 是 Completable,直接返回 RxJava3CallAdapter 对象
    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.
      // 如果是 Completable 它的 `responseType` 直接指定为 Void,也就是 Completable 不需要返回值。
      return new RxJava3CallAdapter(
          Void.class, scheduler, isAsync, false, true, false, false, false, true);
    }

    boolean isFlowable = rawType == Flowable.class;
    boolean isSingle = rawType == Single.class;
    boolean isMaybe = rawType == Maybe.class;
    // 如果 `adatperType` 不是 Flowable,Single,Maybe,Observable 其中之一,直接返回空,表示当前的 adapterType,不能处理直接返回空
    if (rawType != Observable.class && !isFlowable && !isSingle && !isMaybe) {
    
    
      return null;
    }

    boolean isResult = false;
    boolean isBody = false;
    Type responseType;
    // adapterType 中必须有详细的泛型信息,否者报错。
    if (!(returnType instanceof ParameterizedType)) {
    
    
      String name =
          isFlowable ? "Flowable" : isSingle ? "Single" : isMaybe ? "Maybe" : "Observable";
      throw new IllegalStateException(
          name
              + " return type must be parameterized"
              + " as "
              + name
              + "<Foo> or "
              + name
              + "<? extends Foo>");
    }
    // 获取泛型的 type
    Type observableType = getParameterUpperBound(0, (ParameterizedType) returnType);
    // 获取泛型信息的 Class 对象
    Class<?> rawObservableType = getRawType(observableType);
    // 判断泛型类型是否是 Response
    if (rawObservableType == Response.class) {
    
    
      if (!(observableType instanceof ParameterizedType)) {
    
    
        throw new IllegalStateException(
            "Response must be parameterized" + " as Response<Foo> or Response<? extends Foo>");
      }
      // Response 的泛型对象为 responseType 
      responseType = getParameterUpperBound(0, (ParameterizedType) observableType);
    } else if (rawObservableType == Result.class) {
    
    
      // 判断泛型类型是否为 Result 对象
      
      if (!(observableType instanceof ParameterizedType)) {
    
    
        throw new IllegalStateException(
            "Result must be parameterized" + " as Result<Foo> or Result<? extends Foo>");
      }
      // Result 对象的泛型类型为 responseType
      responseType = getParameterUpperBound(0, (ParameterizedType) observableType);
      isResult = true;
    } else {
    
    
       // 其他情况,adapterType 的泛型就是 responseType
      responseType = observableType;
      isBody = true;
    }
    // 构建 RxJava3CallAdapter 对象返回。
    return new RxJava3CallAdapter(
        responseType, scheduler, isAsync, isResult, isBody, isFlowable, isSingle, isMaybe, false);
  }

The first ones RxJava3CallAdatperFactorythat can be processed adapterTypeare Complateable, Single, Maybe, Observableand Flowable.
Here is a brief introduction to the above code:

  1. If adapterTypeyes Complateable, directly construct a return responseTypefor .VoidRxJava3CallAdapter
  2. If adapterTypeis not one of Single, Maybe, Observableand Flowable, return empty directly, indicating that the current adapterTypecannot be processed.
  3. Determine the adapterTypegeneric Classobject in :
  • Response
    As we mentioned when talking about coroutines, this means that the return value requires Response( Retrofit), Responsewhich is the generic type responseType.
  • Result
    ResultThe object is RxJava3CallAdatperFactorydefined in. It will encapsulate successful and failed requests. Usually an exception will be thrown when a request error occurs. After Resultencapsulation, exceptions will not be thrown. Success and exceptions will be encapsulated in Resultthe object. I used to still I implemented such a function myself, but I didn’t expect that there is something ready to use. ResultSo are the generics responseType.
  • In other cases
    , other requests are adapterTypethe generic objects of responseType, which is also the most commonly used case in our development.
  1. Build RxJava3CallAdapterobject.

RxJava3CallAdapter

In the previous article, we learned CallAdapterthat the main responsibility of is to create an object instance through adapt()the method adapterTypeand then return it to the proxied method. Let's take a look at RxJava3CallAdapter#adapt()the implementation of the method:

  @Override
  public Object adapt(Call<R> call) {
    
    
    // 根据同步调用和异步调用构建最基础的 Observable 对象,该流处理的对象是 Response
    Observable<Response<R>> responseObservable =
        isAsync ? new CallEnqueueObservable<>(call) : new CallExecuteObservable<>(call);

    Observable<?> observable;
    // 判断需要的流处理对象的类型,然后在用其他的 Observable 对象封装。
    if (isResult) {
    
    
      // 如果需要 Result 对象,用 ResultObservable 对元素流再封装
      observable = new ResultObservable<>(responseObservable);
    } else if (isBody) {
    
    
      // 如果需要普通 Body,用 BodyObservable 封装
      observable = new BodyObservable<>(responseObservable);
    } else {
    
    
      // 如果是需要有 Response,就用基础的 Observable 对象就好了。
      observable = responseObservable;
    }
    
    // 在 Observable 中添加 scheduler
    if (scheduler != null) {
    
    
      observable = observable.subscribeOn(scheduler);
    }
    
    // 将 Observable 转换成需要的流类型。
    if (isFlowable) {
    
    
      return observable.toFlowable(BackpressureStrategy.LATEST);
    }
    if (isSingle) {
    
    
      return observable.singleOrError();
    }
    if (isMaybe) {
    
    
      return observable.singleElement();
    }
    if (isCompletable) {
    
    
      return observable.ignoreElements();
    }
    return RxJavaPlugins.onAssembly(observable);
  }

Explain the above code:

  1. First, build the foundation based on whether it is an asynchronous call Observable. The implementation class of synchronous call is CallExecuteObservable(analyzed later), the implementation class of asynchronous call is CallEnqueueObservable(analyzed later), and the implementation class of the parameter Callis what we talked about in our previous article OkHttpCall. ObservableThe return data of the basic stream is Response<T>.
  2. Determine the type of stream data required externally. If necessary Result, use (analyzed later) to re-encapsulate BodyObservablethe basic one ; if it needs to be normal , use the re-encapsulation of the basic one ; if it is needed , then the type returned by the basic one is the same. Just use it directly.ObservableBodyBodyObservableObservableResponseObservable
  3. If there is , add one to Schedulerin the previous step , mainly for synchronous calls. The thread for synchronous calls is specified by .OberverbleSchedulerScheduler
  4. Finally, Observableconvert into the required RxJavastream type (return directly if no conversion is required Observable), that is Single, one of Maybe, Flowable, Completable.
CallExecuteObservable

First of all, you must understand that the streams mentioned above RxJavaare all cold streams. The method will be called when subscribing Observable#subscribeActual(), and the real Httptask will be triggered in this method. CallExecuteObservableis the basic stream for synchronous execution, and the data returned by its stream is the complete source code that Response<T>we can look at directly :CallExecuteObservable

final class CallExecuteObservable<T> extends Observable<Response<T>> {
    
    
  private final Call<T> originalCall;

  CallExecuteObservable(Call<T> originalCall) {
    
    
    this.originalCall = originalCall;
  }

  @Override
  protected void subscribeActual(Observer<? super Response<T>> observer) {
    
    
    // Since Call is a one-shot type, clone it for each new observer.
    // 复制 call,因为这个每次流的订阅都会触发新的请求任务,但是一个 Call 只能请求一次,所以这里要复制一个 Call。
    Call<T> call = originalCall.clone();
    // 添加一个 CallDisposable,用来监听流的状态,如果流中途被取消订阅,那么需要把 Call 也取消。
    CallDisposable disposable = new CallDisposable(call);
    observer.onSubscribe(disposable);
    if (disposable.isDisposed()) {
    
    
      return;
    }

    boolean terminated = false;
    try {
    
    
      // 直接同步执行 Http 请求任务。  
      Response<T> response = call.execute();
      
      // 数据返回后检查流是否还存活然后执行 onNext() 和 onComplete() 方法。  
      if (!disposable.isDisposed()) {
    
    
        observer.onNext(response);
      }
      if (!disposable.isDisposed()) {
    
    
        terminated = true;
        observer.onComplete();
      }
    } catch (Throwable t) {
    
    
      Exceptions.throwIfFatal(t);
      if (terminated) {
    
    
        RxJavaPlugins.onError(t);
      } else if (!disposable.isDisposed()) {
    
    
        try {
    
    
          observer.onError(t);
        } catch (Throwable inner) {
    
    
          Exceptions.throwIfFatal(inner);
          RxJavaPlugins.onError(new CompositeException(t, inner));
        }
      }
    }
  }

  private static final class CallDisposable implements Disposable {
    
    
    private final Call<?> call;
    private volatile boolean disposed;

    CallDisposable(Call<?> call) {
    
    
      this.call = call;
    }

    @Override
    public void dispose() {
    
    
      // 如果流取消,把 Call 的任务也取消了。
      disposed = true;
      call.cancel();
    }

    @Override
    public boolean isDisposed() {
    
    
      return disposed;
    }
  }
}

subscribeActual()A brief summary of the method:

  1. Copy call, because each stream subscription will trigger a new request task (the so-called cold stream), but one Callcan only be requested once, so one needs to be copied here Call.
  2. Add CallDisposableto monitor the status of the stream. If the stream has been canceled, Callcancel the task.
  3. Directly call the method to synchronize Call#execute()the request, check the status of the stream after completion, and then call the Observerand onNext()methods onComplete(). If there is an error in the process, call onError()the method.
CallEnqueueObservable

CallEnqueueObservableIt is the basis of asynchronous calls Observable, and the data format returned by its stream is also the same Response<T>. Let’s take a look at its source code:

final class CallEnqueueObservable<T> extends Observable<Response<T>> {
    
    
  private final Call<T> originalCall;

  CallEnqueueObservable(Call<T> originalCall) {
    
    
    this.originalCall = originalCall;
  }

  @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();
    // 构建 CallBallback 对象来监听 Observer 的订阅状态和监听 Http 请求的异步调用
    CallCallback<T> callback = new CallCallback<>(call, observer);
    observer.onSubscribe(callback);
    if (!callback.isDisposed()) {
    
    
      // 异步请求
      call.enqueue(callback);
    }
  }

  private static final class CallCallback<T> implements Disposable, Callback<T> {
    
    
    private final Call<?> call;
    private final Observer<? super Response<T>> observer;
    private volatile boolean disposed;
    boolean terminated = false;

    CallCallback(Call<?> call, Observer<? super Response<T>> observer) {
    
    
      this.call = call;
      this.observer = observer;
    }

    @Override
    public void onResponse(Call<T> call, Response<T> response) {
    
    
      // 请求成功,如果流已经取消就直接返回
      if (disposed) return;
      
      // 执行 Observer 的 onNext() 和 onComplete() 方法
      try {
    
    
        observer.onNext(response);

        if (!disposed) {
    
    
          terminated = true;
          observer.onComplete();
        }
      } catch (Throwable t) {
    
    
        Exceptions.throwIfFatal(t);
        if (terminated) {
    
    
          RxJavaPlugins.onError(t);
        } else if (!disposed) {
    
    
          try {
    
    
            observer.onError(t);
          } catch (Throwable inner) {
    
    
            Exceptions.throwIfFatal(inner);
            RxJavaPlugins.onError(new CompositeException(t, inner));
          }
        }
      }
    }

    @Override
    public void onFailure(Call<T> call, Throwable t) {
    
    
      if (call.isCanceled()) return;
      // 请求失败,调用 Observer 的 onError() 方法
      try {
    
    
        observer.onError(t);
      } catch (Throwable inner) {
    
    
        Exceptions.throwIfFatal(inner);
        RxJavaPlugins.onError(new CompositeException(t, inner));
      }
    }

    @Override
    public void dispose() {
    
    
      // 任务取消。
      disposed = true;
      call.cancel();
    }

    @Override
    public boolean isDisposed() {
    
    
      return disposed;
    }
  }
}

The above method is very simple. The method asynchronous call task subscribeActual()is executed in the method of executing the subscription . The callback of the listening request is the object, which is also the object of the listening stream cancellation. In the callback of , it indicates that the request is successful. If the stream is not canceled, the and method of is called accordingly . If an error occurs in the process, the method is called. The callback of Ziah indicates that the request failed, and the method of is called directly .Call#enqueue()HttpCallCallback
CallCallback#onResponse()ObserveronNext()onComplete()onError()
CallCallback#onFailure()ObserveronError()

ResultObservable

ResultObservableIt converts the basic return Response<T>stream Observableinto a return Result<T>stream. It will never trigger onError(). Success and failure will be encapsulated in Resultthe object. Let's take a look at its implementation:

final class ResultObservable<T> extends Observable<Result<T>> {
    
    
  private final Observable<Response<T>> upstream;

  ResultObservable(Observable<Response<T>> upstream) {
    
    
    this.upstream = upstream;
  }

  @Override
  protected void subscribeActual(Observer<? super Result<T>> observer) {
    
    
    // 将上层流传过来的数据用 ResultObserver 对象来监听
    upstream.subscribe(new ResultObserver<>(observer));
  }

  private static class ResultObserver<R> implements Observer<Response<R>> {
    
    
    private final Observer<? super Result<R>> observer;

    ResultObserver(Observer<? super Result<R>> observer) {
    
    
      this.observer = observer;
    }

    @Override
    public void onSubscribe(Disposable disposable) {
    
    
      observer.onSubscribe(disposable);
    }

    @Override
    public void onNext(Response<R> response) {
    
    
      // 请求成功,把 Response 用 Result 封装,然后调用 `Observer#onNext()` 方法传递给下游。
      observer.onNext(Result.response(response));
    }

    @Override
    public void onError(Throwable throwable) {
    
    
      // 请求异常,把 `Throwable` 用 Result 封装,然后调用 `Observer#onNext()` 方法传递给下游
      try {
    
    
        observer.onNext(Result.error(throwable));
      } catch (Throwable t) {
    
    
        try {
    
    
          observer.onError(t);
        } catch (Throwable inner) {
    
    
          Exceptions.throwIfFatal(inner);
          RxJavaPlugins.onError(new CompositeException(t, inner));
        }
        return;
      }
      observer.onComplete();
    }

    @Override
    public void onComplete() {
    
    
      observer.onComplete();
    }
  }
}

In the method, use the object to monitor subscribeActual()the data flowing from the upper layer . In the method, it means that the request is successful, encapsulate it with and pass it to the downstream through the method ; in the method, it means that the request failed, encapsulate the object with the method, and pass it to the downstream through the method. downstream .ResultObserverResultObserver#onNext()Response<T>Result<T>Observer#onNext()ObserverResultObserver#onError()ThrowableResult<T>Observer#onNext()Observer

BodyObservable

BodyObservableIts job is to simply convert the data in the basic Observerablestream Response<T>into ResponseBody. It works ResultObservablesimilarly to , except that it does not intercept exception information:

final class BodyObservable<T> extends Observable<T> {
    
    
  private final Observable<Response<T>> upstream;

  BodyObservable(Observable<Response<T>> upstream) {
    
    
    this.upstream = upstream;
  }

  @Override
  protected void subscribeActual(Observer<? super T> observer) {
    
    
    upstream.subscribe(new BodyObserver<>(observer));
  }

  private static class BodyObserver<R> implements Observer<Response<R>> {
    
    
    private final Observer<? super R> observer;
    private boolean terminated;

    BodyObserver(Observer<? super R> observer) {
    
    
      this.observer = observer;
    }

    @Override
    public void onSubscribe(Disposable disposable) {
    
    
      observer.onSubscribe(disposable);
    }

    @Override
    public void onNext(Response<R> response) {
    
    
      if (response.isSuccessful()) {
    
    
        // 成功直接取 ResponseBody 传递到下游去。
        observer.onNext(response.body());
      } else {
    
    
        // 请求失败
        terminated = true;
        Throwable t = new HttpException(response);
        try {
    
    
          observer.onError(t);
        } catch (Throwable inner) {
    
    
          Exceptions.throwIfFatal(inner);
          RxJavaPlugins.onError(new CompositeException(t, inner));
        }
      }
    }

    @Override
    public void onComplete() {
    
    
      if (!terminated) {
    
    
        observer.onComplete();
      }
    }

    @Override
    public void onError(Throwable throwable) {
    
    
      if (!terminated) {
    
    
        observer.onError(throwable);
      } else {
    
    
        // This should never happen! onNext handles and forwards errors automatically.
        Throwable broken =
            new AssertionError(
                "This should never happen! Report as a bug with the full stacktrace.");
        //noinspection UnnecessaryInitCause Two-arg AssertionError constructor is 1.7+ only.
        broken.initCause(throwable);
        RxJavaPlugins.onError(broken);
      }
    }
  }
}

The above code is ResultObservablevery similar to , so there isn’t much to say.

MoshiConverterFactory

If you are not familiar Moshiwith , you can learn about it. If you use KotlinDevelop, there are still many advantages Moshiover the old and frail . It is recommended that students who are still using Develop migrate to .GsonGsonMoshi

MoshiConverterFactoryThe instance is created through MoshiConverterFactory#create()the method. You can pass in a custom Moshiobject. If not, MoshiConverterFactorya default one will be created for you.

Let's take a look at Converter.Factorythe important methods of this abstract class:

  abstract class Factory {
    
    
  
    public @Nullable Converter<ResponseBody, ?> responseBodyConverter(
        Type type, Annotation[] annotations, Retrofit retrofit) {
    
    
      return null;
    }

    public @Nullable Converter<?, RequestBody> requestBodyConverter(
        Type type,
        Annotation[] parameterAnnotations,
        Annotation[] methodAnnotations,
        Retrofit retrofit) {
    
    
      return null;
    }
    
    public @Nullable Converter<?, String> stringConverter(
        Type type, Annotation[] annotations, Retrofit retrofit) {
    
    
      return null;
    }
     // ...
  }

  • responseBodyConverter()
    When building a request task, you need to use this method to obtain the object that will be ResponseBodyconverted into the target object Converter. After the request is successful, it is directly used Converterfor conversion.

  • requestBodyConverter()
    When constructing a request, you need to use this method to obtain the target object converted into RequestBody( Converterit will be obtained only when @Body/ is available). When conversion is needed, use conversion directly.@PartConverter

  • stringConverter()
    Obtain and convert other objects into Stringobjects Converter. For example, when constructing a request, @Querythe annotation-modified parameters need to be converted into Stringobjects, and this method will be used to obtain the corresponding ones Converter.

MoshiConverterFactoryIt implements responseBodyConverter()the and requestBodyConverter()methods, which means it does not support conversion from other objects String.

MoshiRequestBodyConverter

Let’s first look at MoshiConverterFactory#requestBodyConverter()the implementation of the method:

  @Override
  public Converter<?, RequestBody> requestBodyConverter(
      Type type,
      Annotation[] parameterAnnotations,
      Annotation[] methodAnnotations,
      Retrofit retrofit) {
    
    
    // 根据输入的 Type 获取 Moshi 的 JsonAdapter
    JsonAdapter<?> adapter = moshi.adapter(type, jsonAnnotations(parameterAnnotations));
    // 更新 JsonAdapter的 配置
    if (lenient) {
    
    
      adapter = adapter.lenient();
    }
    if (failOnUnknown) {
    
    
      adapter = adapter.failOnUnknown();
    }
    if (serializeNulls) {
    
    
      adapter = adapter.serializeNulls();
    }
    // 创建 Converter 对象。
    return new MoshiRequestBodyConverter<>(adapter);
  }

Let’s briefly talk about it. ConverterIts first paradigm represents the input type, and the second parameter represents the converted type. The conversion is done through convert()the method. Then look at the code above:

  1. MoshiObtain the object in through the input type JsonAdatper. Serialization/deserialization all rely on this object.
  2. Updated JsonAdatperconfiguration.
  3. Create MoshiRequestBodyConverterobject return method.

Let's take a look at MoshiRequestBodyConverter#convert()how the method is converted:

  @Override
  public RequestBody convert(T value) throws IOException {
    
    
    // 创建 OkIo 的 Buffer 对象.
    Buffer buffer = new Buffer();
    // 以 Buffer 为参数创建一个 JsonWriter 对象。
    JsonWriter writer = JsonWriter.of(buffer);
    // 将转换后的对象写入到 Buffer 中。
    adapter.toJson(writer, value);
    // 构建类型为 `application/json; charset=UTF-8` 的 RequestBody
    return RequestBody.create(MEDIA_TYPE, buffer.readByteString());
  }

The above code is very simple:

  1. First, an object OkIoof is constructed Buffer, and then Bufferan object is created from the object JsonWriter.
  2. JsonAdapter#toJson()Write the serialized data into via the method Buffer.
  3. Convert Bufferthe data in Stringand then construct a type application/json; charset=UTF-8of RequestBody.

MoshiResponseBodyConverter

Let’s take a look at MoshiConverterFactory#responseBodyConverter()the implementation of the method:

  @Override
  public Converter<ResponseBody, ?> responseBodyConverter(
      Type type, Annotation[] annotations, Retrofit retrofit) {
    
    
    JsonAdapter<?> adapter = moshi.adapter(type, jsonAnnotations(annotations));
    if (lenient) {
    
    
      adapter = adapter.lenient();
    }
    if (failOnUnknown) {
    
    
      adapter = adapter.failOnUnknown();
    }
    if (serializeNulls) {
    
    
      adapter = adapter.serializeNulls();
    }
    return new MoshiResponseBodyConverter<>(adapter);
  }

requestBodyConverterConstructs one in almost the same way JsonAdapteras and returns MoshiResponseBodyConverterthe object.

Let’s take a look at MoshiResponseBodyConverter#convert()the implementation of the method:

  @Override
  public T convert(ResponseBody value) throws IOException {
    
    
    // 获取 ResponseBody 中的 Source(OkIo) 对象。
    BufferedSource source = value.source();
    try {
    
    
      // Moshi has no document-level API so the responsibility of BOM skipping falls to whatever
      // is delegating to it. Since it's a UTF-8-only library as well we only honor the UTF-8 BOM.
      // 判断开头的 3 个字节是否是 `0xEFBBBF`,如果是就跳过这几个字节
      if (source.rangeEquals(0, UTF8_BOM)) {
    
    
        source.skip(UTF8_BOM.size());
      }
      // 构建 JsonReader 对象
      JsonReader reader = JsonReader.of(source);
      // 读取 JsonReader 中的数据,然后反序列化为目标对象。
      T result = adapter.fromJson(reader);
      // 检查是否已经读取完成
      if (reader.peek() != JsonReader.Token.END_DOCUMENT) {
    
    
        throw new JsonDataException("JSON document was not fully consumed.");
      }
      return result;
    } finally {
    
    
      value.close();
    }
  }

To briefly summarize the above code:

  1. Get the ( ) object ResponseBodyin .SourceOkIo
  2. Determine Sourcewhether the first 3 bytes in the object are 0xEFBBBF, and skip if so.
  3. SourceConstruct JsonReader( Moshi) object via .
  4. JsonAdatper#fromJson()Read the data in the method and JsonReaderthen deserialize it into the target object.
  5. Check whether JsonReaderthe in Jsonhas been read correctly, and finally return the deserialized object.

Summarize

Today, we will use source code analysis Retrofitof the official implementation of RxJava3CallAdapterFactoryand MoshiConverterFactoryto let everyone know how to customize an excellent CallAdapterFactoryand ConverterFactory. If you are interested in other CallAdapterFactoryor ConverterFactory, you can also take a look at their implementation.

at last

If you want to become an architect or want to break through the 20-30K salary range, then don't be limited to coding and business, you must be able to select and expand, and improve your programming thinking. In addition, good career planning is also very important, and learning habits are important, but the most important thing is to be able to persevere. Any plan that cannot be implemented consistently is empty talk.

If you have no direction, here is a set of "Advanced Notes on the Eight Modules of Android" written by a senior architect at Alibaba to help you systematically organize messy, scattered, and fragmented knowledge, so that you can systematically and efficiently Master various knowledge points of Android development.
img
Compared with the fragmented content we usually read, the knowledge points in this note are more systematic, easier to understand and remember, and are strictly arranged according to the knowledge system.

Welcome everyone to support with one click and three links. If you need the information in the article, just scan the CSDN official certification WeChat card at the end of the article to get it for free↓↓↓ (There is also a small bonus of ChatGPT robot at the end of the article, don’t miss it)

PS: There is also a ChatGPT robot in the group, which can answer everyone’s work or technical questions.

picture

Guess you like

Origin blog.csdn.net/Androiddddd/article/details/135279625