分析下Retrofit為何如此優(yōu)秀瓦堵?

What柒巫?

它是Square公司開發(fā)的一個(gè)強(qiáng)大的網(wǎng)絡(luò)庫(kù)!基于Okhttp谷丸,支持RxJava。

Why?

為什么要學(xué)它应结,因?yàn)樗鼉?yōu)秀刨疼!不信你點(diǎn)擊下圖看看!

  • 功能強(qiáng)大
    1.基于Okhttp&遵循Restful API設(shè)計(jì)風(fēng)格
    2.通過(guò)注解配置網(wǎng)絡(luò)請(qǐng)求參數(shù)
    4.支持同步&異步網(wǎng)絡(luò)請(qǐng)求
    5.支持多種數(shù)據(jù)解析&序列化格式(Gson,Json,XML鹅龄,Protobuf)
    6.提供RxJava支持

  • 優(yōu)點(diǎn)
    功能強(qiáng)大揩慕,簡(jiǎn)潔易用,可擴(kuò)展性好

HOW?

說(shuō)了這么多用個(gè)試試扮休!

public interface ApiService {
    @GET("/")
    Call<ResponseBody> getRetrofitTest();
}

 public  void retrofit(){
        Retrofit retrofit =new Retrofit.Builder().baseUrl("https://www.baidu.com").build();
        ApiService apiService=retrofit.create(ApiService.class);
        apiService.getRetrofitTest().enqueue(new Callback<ResponseBody>() {
            @Override
            public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
                Log.i("retrofit",response.message());
            }

            @Override
            public void onFailure(Call<ResponseBody> call, Throwable t) {
                Log.i("retrofit",t.toString());
            }
        });
    } 

更多使用詳解

Code分析

基本流程

1.使用建造者模式實(shí)例化Retrofit
Retrofit   retrofit   = new Retrofit.Builder().baseUrl("https://www.baidu.com").addConverterFactory
(GsonConverterFactory.create()).build();
2.使用注解方式構(gòu)建Call請(qǐng)求方法| 參數(shù)...
 @GET("/")
    Call<ResponseBody> getRetrofitTest();
3.使用動(dòng)態(tài)代理實(shí)現(xiàn)請(qǐng)求接口
 ApiService apiService = retrofit.create(ApiService.class);
4.異步請(qǐng)求方法調(diào)用迎卤,回調(diào)返回結(jié)果
apiService.getRetrofitTest().enqueue(new Callback<ResponseBody>() {
            @Override
            public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
                Log.i("retrofit", response.message());
            }

            @Override
            public void onFailure(Call<ResponseBody> call, Throwable t) {
                Log.i("retrofit", t.toString());
            }
        });

流程詳解

流程1

Builder模式實(shí)例化retrofit三步驟

Retrofit   retrofit   = new Retrofit.Builder().baseUrl("https://www.baidu.com").addConverterFactory
(GsonConverterFactory.create()).build();
步驟 1

這個(gè)函數(shù)做了什么呢?

1.對(duì)變量是否為空判斷玷坠,并附上默認(rèn)的值
2.然后new 出retrofit

public Retrofit build() {
      if (baseUrl == null) {
        throw new IllegalStateException("Base URL required.");
      }

      okhttp3.Call.Factory callFactory = this.callFactory;
      if (callFactory == null) {
        callFactory = new OkHttpClient();
      }

      Executor callbackExecutor = this.callbackExecutor;
      if (callbackExecutor == null) {
        callbackExecutor = platform.defaultCallbackExecutor();
      }

      // Make a defensive copy of the adapters and add the default Call adapter.
      List<CallAdapter.Factory> callAdapterFactories = new ArrayList<>(this.callAdapterFactories);
      callAdapterFactories.addAll(platform.defaultCallAdapterFactories(callbackExecutor));

      // Make a defensive copy of the converters.
      List<Converter.Factory> converterFactories = new ArrayList<>(
          1 + this.converterFactories.size() + platform.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(platform.defaultConverterFactories());
      return new Retrofit(callFactory, baseUrl, unmodifiableList(converterFactories),
          unmodifiableList(callAdapterFactories), callbackExecutor, validateEagerly);
    }
  }
步驟2 設(shè)置配置參數(shù)

這里只是舉兩個(gè)配置參數(shù)的例子

    public Builder baseUrl(HttpUrl baseUrl) {
      checkNotNull(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;
    }
    /** Add converter factory for serialization and deserialization of objects. */
    public Builder addConverterFactory(Converter.Factory factory) {
      converterFactories.add(checkNotNull(factory, "factory == null"));
      return this;
    }
步驟3 分析Retrofit常量&方法
public final class Retrofit {
  private final Map<Method, ServiceMethod<?>> serviceMethodCache = new ConcurrentHashMap<>();

  final okhttp3.Call.Factory callFactory;
  final HttpUrl baseUrl;//請(qǐng)求URL
  final List<Converter.Factory> converterFactories;//數(shù)據(jù)轉(zhuǎn)換器集合
  final List<CallAdapter.Factory> callAdapterFactories;//網(wǎng)絡(luò)請(qǐng)求適配器集合
  final @Nullable Executor callbackExecutor;//線程切換執(zhí)行器
  final boolean validateEagerly;//驗(yàn)證

  Retrofit(okhttp3.Call.Factory callFactory, HttpUrl baseUrl,
      List<Converter.Factory> converterFactories, List<CallAdapter.Factory> callAdapterFactories,
      @Nullable Executor callbackExecutor, boolean validateEagerly) {
    this.callFactory = callFactory;
    this.baseUrl = baseUrl;
    this.converterFactories = converterFactories; // Copy+unmodifiable at call site.
    this.callAdapterFactories = callAdapterFactories; // Copy+unmodifiable at call site.
    this.callbackExecutor = callbackExecutor;
    this.validateEagerly = validateEagerly;
  }

變量詳解

1.HttpUrl baseUrl
   /**
    * Set the API base URL.
    *
    * @see #baseUrl(HttpUrl)
    *把String類型的url參數(shù)轉(zhuǎn)化為適合OKhttp的HttpUrl類型
    */
   public Builder baseUrl(String baseUrl) {
     checkNotNull(baseUrl, "baseUrl == null");
     return baseUrl(HttpUrl.get(baseUrl));
   }
  /**
    * Set the API base URL.
    *
    * @see #baseUrl(HttpUrl)
    */
   public Builder baseUrl(URL baseUrl) {
     checkNotNull(baseUrl, "baseUrl == null");
     return baseUrl(HttpUrl.get(baseUrl.toString()));
   }
  /**
    * Set the API base URL.
    *
    * @see #baseUrl(URL)
    */

public Builder baseUrl(HttpUrl baseUrl) {
     checkNotNull(baseUrl, "baseUrl == null");//檢測(cè)是否空
     List<String> pathSegments = baseUrl.pathSegments();//切割判斷
     //判斷最后一個(gè)字段要以 / 結(jié)尾
     if (!"".equals(pathSegments.get(pathSegments.size() - 1))) {
       throw new IllegalArgumentException("baseUrl must end in /: " + baseUrl);
     }
     this.baseUrl = baseUrl;
     return this;
   }
2. final List<Converter.Factory> converterFactories;

數(shù)據(jù)轉(zhuǎn)換器工廠的集合
作用:放置數(shù)據(jù)轉(zhuǎn)換器工廠
數(shù)據(jù)轉(zhuǎn)換器工廠作用:生產(chǎn)數(shù)據(jù)轉(zhuǎn)換器(converter)

   /** Add converter factory for serialization and deserialization of objects. 
  *添加轉(zhuǎn)換器工廠以進(jìn)行對(duì)象的序列化和反序列化蜗搔。
  * */
   public Builder addConverterFactory(Converter.Factory factory) {
     converterFactories.add(checkNotNull(factory, "factory == null"));
     return this;
   }

所有定義只要實(shí)現(xiàn)Converter這個(gè)接口,數(shù)據(jù)F轉(zhuǎn)換T

public interface Converter<F, T> {
   //實(shí)現(xiàn)從 F(rom) 到 T(o)的轉(zhuǎn)換
   @Nullable T convert(F value) throws IOException;

   /** Creates {@link Converter} instances based on a type and target usage. */
   abstract class Factory {
       /**
        * 這里創(chuàng)建從ResponseBody其它類型的Converter劲藐,如果不能處理返回null
        * 主要用于對(duì)響應(yīng)體的處理
        */
       public @Nullable Converter<ResponseBody, ?> responseBodyConverter(Type type,
                                                                         Annotation[] annotations, Retrofit retrofit) {
           return null;
       }

       /**
        在這里創(chuàng)建 從自定類型到RequestBody 的Converter,不能處理就返回null,
        主要用于對(duì)Part樟凄、PartMap聘芜、Body注解的處理
        */
       public @Nullable Converter<?, RequestBody> requestBodyConverter(Type type,
                                                                       Annotation[] parameterAnnotations, Annotation[] methodAnnotations, Retrofit retrofit) {
           return null;
       }

       /**
        這里用于對(duì)Field、FieldMap缝龄、Header汰现、Path、Query叔壤、QueryMap注解的處理
         Retrfofit對(duì)于上面的幾個(gè)注解默認(rèn)使用的是調(diào)用toString方法
        */
       public @Nullable Converter<?, String> stringConverter(Type type, Annotation[] annotations,
                                                             Retrofit retrofit) {
           return null;
       }

       /**
        * 根據(jù)下標(biāo)index,提取泛型參數(shù)
        */
       protected static Type getParameterUpperBound(int index, ParameterizedType type) {
           return Utils.getParameterUpperBound(index, type);
       }

       /**
        * 根據(jù)泛型提取類
        */
       protected static Class<?> getRawType(Type type) {
           return Utils.getRawType(type);
       }
   }
}
3. final List<CallAdapter.Factory> callAdapterFactories;

網(wǎng)絡(luò)請(qǐng)求適配器工廠的集合
作用:放置網(wǎng)絡(luò)請(qǐng)求適配器工廠
網(wǎng)絡(luò)請(qǐng)求適配器工廠作用:生產(chǎn)網(wǎng)絡(luò)請(qǐng)求適配器(CallAdapter)
Call在Retrofit里默認(rèn)是OkHttpCall

/**
* 網(wǎng)絡(luò)請(qǐng)求適配器
* @param <T>
*/
final class OkHttpCall<T> implements Call<T> {
   private final RequestFactory             requestFactory;
   private final Object[]                   args;
   private final okhttp3.Call.Factory       callFactory;
   private final Converter<ResponseBody, T> responseConverter;
   private volatile boolean canceled;
   @GuardedBy("this")
   private @Nullable okhttp3.Call rawCall;
   @GuardedBy("this") // Either a RuntimeException, non-fatal Error, or IOException.
   private @Nullable Throwable creationFailure;
   @GuardedBy("this")
   private boolean executed;
   // 構(gòu)造方法
   OkHttpCall(RequestFactory requestFactory, Object[] args,
              okhttp3.Call.Factory callFactory, Converter<ResponseBody, T> responseConverter) {
       this.requestFactory = requestFactory;
       this.args = args;
       this.callFactory = callFactory;
       this.responseConverter = responseConverter;
   }

   @SuppressWarnings("CloneDoesntCallSuperClone") // We are a final type & this saves clearing state.
   @Override public retrofit2.OkHttpCall<T> clone() {
       return new retrofit2.OkHttpCall<>(requestFactory, args, callFactory, responseConverter);
   }

   @Override public synchronized Request request() {
       okhttp3.Call call = rawCall;
       if (call != null) {
           return call.request();
       }
       if (creationFailure != null) {
           if (creationFailure instanceof IOException) {
               throw new RuntimeException("Unable to create request.", creationFailure);
           } else if (creationFailure instanceof RuntimeException) {
               throw (RuntimeException) creationFailure;
           } else {
               throw (Error) creationFailure;
           }
       }
       try {
           return (rawCall = createRawCall()).request();
       } catch (RuntimeException | Error e) {
           throwIfFatal(e); // Do not assign a fatal error to creationFailure.
           creationFailure = e;
           throw e;
       } catch (IOException e) {
           creationFailure = e;
           throw new RuntimeException("Unable to create request.", e);
       }
   }
   //異步執(zhí)行網(wǎng)絡(luò)請(qǐng)求
   @Override public void enqueue(final Callback<T> callback) {
       checkNotNull(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 {
                   //獲取真正的網(wǎng)絡(luò)請(qǐng)求對(duì)象
                   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) {
               Response<T> response;
               try {
                   response = parseResponse(rawResponse);
               } catch (Throwable e) {
                   throwIfFatal(e);
                   callFailure(e);
                   return;
               }

               try {
                   callback.onResponse(retrofit2.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(retrofit2.OkHttpCall.this, e);
               } catch (Throwable t) {
                   throwIfFatal(t);
                   t.printStackTrace(); // TODO this is not great
               }
           }
       });
   }

   @Override public synchronized boolean isExecuted() {
       return executed;
   }
   //同步執(zhí)行網(wǎng)絡(luò)請(qǐng)求方法
   @Override public Response<T> execute() throws IOException {
       okhttp3.Call call;

       synchronized (this) {
           if (executed) throw new IllegalStateException("Already executed.");
           executed = true;

           if (creationFailure != null) {
               if (creationFailure instanceof IOException) {
                   throw (IOException) creationFailure;
               } else if (creationFailure instanceof RuntimeException) {
                   throw (RuntimeException) creationFailure;
               } else {
                   throw (Error) creationFailure;
               }
           }

           call = rawCall;
           if (call == null) {
               try {
                   call = rawCall = createRawCall();
               } catch (IOException | RuntimeException | Error e) {
                   throwIfFatal(e); //  Do not assign a fatal error to creationFailure.
                   creationFailure = e;
                   throw e;
               }
           }
       }

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

       return parseResponse(call.execute());
   }

   private okhttp3.Call createRawCall() throws IOException {
       okhttp3.Call call = callFactory.newCall(requestFactory.create(args));
       if (call == null) {
           throw new NullPointerException("Call.Factory returned null.");
       }
       return call;
   }
   //解析網(wǎng)絡(luò)返回?cái)?shù)據(jù)
   Response<T> parseResponse(okhttp3.Response rawResponse) throws IOException {
       ResponseBody rawBody = rawResponse.body();

       // Remove the body's source (the only stateful object) so we can pass the response along.
       rawResponse = rawResponse.newBuilder()
               .body(new retrofit2.OkHttpCall.NoContentResponseBody(rawBody.contentType(), rawBody.contentLength()))
               .build();

       int code = rawResponse.code();
       if (code < 200 || code >= 300) {
           try {
               // Buffer the entire body to avoid future I/O.
               ResponseBody bufferedBody = Utils.buffer(rawBody);
               return Response.error(bufferedBody, rawResponse);
           } finally {
               rawBody.close();
           }
       }

       if (code == 204 || code == 205) {
           rawBody.close();
           return Response.success(null, rawResponse);
       }

       retrofit2.OkHttpCall.ExceptionCatchingResponseBody catchingBody = new retrofit2.OkHttpCall.ExceptionCatchingResponseBody(rawBody);
       try {
           //格式轉(zhuǎn)換
           T body = responseConverter.convert(catchingBody);
           return Response.success(body, rawResponse);
       } catch (RuntimeException e) {
           // If the underlying source threw an exception, propagate that rather than indicating it was
           // a runtime exception.
           catchingBody.throwIfCaught();
           throw e;
       }
   }

   public void cancel() {
       canceled = true;

       okhttp3.Call call;
       synchronized (this) {
           call = rawCall;
       }
       if (call != null) {
           call.cancel();
       }
   }

   @Override public boolean isCanceled() {
       if (canceled) {
           return true;
       }
       synchronized (this) {
           return rawCall != null && rawCall.isCanceled();
       }
   }

   static final class NoContentResponseBody extends ResponseBody {
       private final @Nullable
       MediaType contentType;
       private final long      contentLength;

       NoContentResponseBody(@Nullable MediaType contentType, long contentLength) {
           this.contentType = contentType;
           this.contentLength = contentLength;
       }

       @Override public MediaType contentType() {
           return contentType;
       }

       @Override public long contentLength() {
           return contentLength;
       }

       @Override public BufferedSource source() {
           throw new IllegalStateException("Cannot read raw response body of a converted body.");
       }
   }

   static final class ExceptionCatchingResponseBody extends ResponseBody {
       private final ResponseBody delegate;
       private final BufferedSource delegateSource;
       @Nullable IOException thrownException;

       ExceptionCatchingResponseBody(ResponseBody delegate) {
           this.delegate = delegate;
           this.delegateSource = Okio.buffer(new ForwardingSource(delegate.source()) {
               @Override public long read(Buffer sink, long byteCount) throws IOException {
                   try {
                       return super.read(sink, byteCount);
                   } catch (IOException e) {
                       thrownException = e;
                       throw e;
                   }
               }
           });
       }

       @Override public MediaType contentType() {
           return delegate.contentType();
       }

       @Override public long contentLength() {
           return delegate.contentLength();
       }

       @Override public BufferedSource source() {
           return delegateSource;
       }

       @Override public void close() {
           delegate.close();
       }

       void throwIfCaught() throws IOException {
           if (thrownException != null) {
               throw thrownException;
           }
       }
   }
}

在Retrofit中提供了四種CallAdapterFactory: ExecutorCallAdapterFactory(默認(rèn))瞎饲、GuavaCallAdapterFactory、Java8CallAdapterFactory炼绘、RxJavaCallAdapterFactory

4. private @Nullable Executor callbackExecutor;線程切換
   @Override public Executor defaultCallbackExecutor() {
     return new MainThreadExecutor();
   }

 static class MainThreadExecutor implements Executor {
     private final Handler handler = new Handler(Looper.getMainLooper());
     //切換到主線程顯示結(jié)果
     @Override public void execute(Runnable r) {
       handler.post(r);
     }
   }


@Override public void enqueue(final Callback<T> callback) {
     checkNotNull(callback, "callback == null");

     delegate.enqueue(new Callback<T>() {
       @Override public void onResponse(Call<T> call, final Response<T> response) {
       //線程切換
         callbackExecutor.execute(new Runnable() {
           @Override public void run() {
             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(new Runnable() {
           @Override public void run() {
             callback.onFailure(ExecutorCallbackCall.this, t);
           }
         });
       }
     });
   }
5. final boolean validateEagerly;判斷是否需要驗(yàn)證
 if (validateEagerly) {
     eagerlyValidateMethods(service);
   }
6.private final Map<Method, ServiceMethod<?>> serviceMethodCache = new ConcurrentHashMap<>();

網(wǎng)絡(luò)請(qǐng)求配置對(duì)象(對(duì)網(wǎng)絡(luò)請(qǐng)求接口中方法注解進(jìn)行解析后得到的對(duì)象)
作用:存儲(chǔ)網(wǎng)絡(luò)請(qǐng)求相關(guān)的配置嗅战,如網(wǎng)絡(luò)請(qǐng)求的方法蛛淋、數(shù)據(jù)轉(zhuǎn)換器逐样、網(wǎng)絡(luò)請(qǐng)求適配器、網(wǎng)絡(luò)請(qǐng)求//工廠劫侧、基地址等

/**
*通過(guò)注解方式獲取配置對(duì)象 實(shí)現(xiàn)緩存
*/
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;
 }



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;
     }
   }
主要分方法
1.動(dòng)態(tài)方法實(shí)現(xiàn)注解接口
public <T> T create(final Class<T> service) {
    Utils.validateServiceInterface(service);
    if (validateEagerly) {
      eagerlyValidateMethods(service);
    }
    return (T) Proxy.newProxyInstance(service.getClassLoader(), new Class<?>[] { service },
        new InvocationHandler() {
          private final Platform platform = Platform.get();
          private final Object[] emptyArgs = new Object[0];

          @Override public Object invoke(Object proxy, Method method, @Nullable Object[] args)
              throws Throwable {
            // If the method is a method from Object then defer to normal invocation.
            if (method.getDeclaringClass() == Object.class) {
              return method.invoke(this, args);
            }
            if (platform.isDefaultMethod(method)) {
              return platform.invokeDefaultMethod(method, service, proxy, args);
            }
            return loadServiceMethod(method).invoke(args != null ? args : emptyArgs);
          }
        });
  }
2.解析緩存注解等參數(shù)
  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;
  }
3.網(wǎng)絡(luò)請(qǐng)求適配器
  @Override ReturnT invoke(Object[] args) {
    return callAdapter.adapt(
        new OkHttpCall<>(requestFactory, args, callFactory, responseConverter));
  }
4.實(shí)現(xiàn)適配器方法
      @Override public Call<Object> adapt(Call<Object> call) {
        return new ExecutorCallbackCall<>(callbackExecutor, call);
      }
5.正真的請(qǐng)求和返回參數(shù)的類
final class ExecutorCallAdapterFactory extends CallAdapter.Factory {
  final Executor callbackExecutor;

  ExecutorCallAdapterFactory(Executor callbackExecutor) {
    this.callbackExecutor = callbackExecutor;
  }

  @Override public @Nullable CallAdapter<?, ?> get(
      Type returnType, Annotation[] annotations, Retrofit retrofit) {
    if (getRawType(returnType) != Call.class) {
      return null;
    }
    final Type responseType = Utils.getCallResponseType(returnType);
    return new CallAdapter<Object, Call<?>>() {
      @Override public Type responseType() {
        return responseType;
      }

      @Override public Call<Object> adapt(Call<Object> call) {
        return new ExecutorCallbackCall<>(callbackExecutor, call);
      }
    };
  }

  static final class ExecutorCallbackCall<T> implements Call<T> {
    final Executor callbackExecutor;
    final Call<T> delegate;

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

    @Override public void enqueue(final Callback<T> callback) {
      checkNotNull(callback, "callback == null");

      delegate.enqueue(new Callback<T>() {
        @Override public void onResponse(Call<T> call, final Response<T> response) {
          callbackExecutor.execute(new Runnable() {
            @Override public void run() {
              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(new Runnable() {
            @Override public void run() {
              callback.onFailure(ExecutorCallbackCall.this, t);
            }
          });
        }
      });
    }

    @Override public boolean isExecuted() {
      return delegate.isExecuted();
    }

    @Override public Response<T> execute() throws IOException {
      return delegate.execute();
    }

    @Override public void cancel() {
      delegate.cancel();
    }

    @Override public boolean isCanceled() {
      return delegate.isCanceled();
    }

    @SuppressWarnings("CloneDoesntCallSuperClone") // Performing deep clone.
    @Override public Call<T> clone() {
      return new ExecutorCallbackCall<>(callbackExecutor, delegate.clone());
    }

    @Override public Request request() {
      return delegate.request();
    }
  }
}
結(jié)合RxJava用RxJava2CallAdapter
//第一步創(chuàng)建工廠CallAdapterFactory
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
//第二步實(shí)例化工廠方法
  public static RxJava2CallAdapterFactory create() {
    return new RxJava2CallAdapterFactory(null, false);
  }
//第三步創(chuàng)建網(wǎng)絡(luò)適配器RxJava2CallAdapter
  public CallAdapter<?, ?> get(Type returnType, Annotation[] annotations, Retrofit retrofit) {
    Class<?> rawType = getRawType(returnType);

    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.
      return new RxJava2CallAdapter(Void.class, scheduler, isAsync, false, true, false, false,
          false, true);
    }
//第四步傳入Call請(qǐng)求器到RxJava2CallAdapter
 @Override public Object adapt(Call<R> call) {
    Observable<Response<R>> responseObservable = isAsync
        ? new CallEnqueueObservable<>(call)
        : new CallExecuteObservable<>(call);

    Observable<?> observable;
    if (isResult) {
      observable = new ResultObservable<>(responseObservable);
    } else if (isBody) {
      observable = new BodyObservable<>(responseObservable);
    } else {
      observable = responseObservable;
    }

    if (scheduler != null) {
      observable = observable.subscribeOn(scheduler);
    }

    if (isFlowable) {
      return observable.toFlowable(BackpressureStrategy.LATEST);
    }
    if (isSingle) {
      return observable.singleOrError();
    }
    if (isMaybe) {
      return observable.singleElement();
    }
    if (isCompletable) {
      return observable.ignoreElements();
    }
    return observable;
  }
//第五步具體實(shí)現(xiàn)方法
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();
    CallCallback<T> callback = new CallCallback<>(call, observer);
    observer.onSubscribe(callback);
    call.enqueue(callback);
  }

  private static final class CallCallback<T> implements Disposable, Callback<T> {
    private final Call<?> call;
    private final Observer<? super Response<T>> observer;
    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 (call.isCanceled()) return;

      try {
        observer.onNext(response);

        if (!call.isCanceled()) {
          terminated = true;
          observer.onComplete();
        }
      } catch (Throwable t) {
        if (terminated) {
          RxJavaPlugins.onError(t);
        } else if (!call.isCanceled()) {
          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;

      try {
        observer.onError(t);
      } catch (Throwable inner) {
        Exceptions.throwIfFatal(inner);
        RxJavaPlugins.onError(new CompositeException(t, inner));
      }
    }

    @Override public void dispose() {
      call.cancel();
    }

    @Override public boolean isDisposed() {
      return call.isCanceled();
    }
  }
}

image.png
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末铅辞,一起剝皮案震驚了整個(gè)濱河市厌漂,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌斟珊,老刑警劉巖苇倡,帶你破解...
    沈念sama閱讀 211,639評(píng)論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異囤踩,居然都是意外死亡旨椒,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,277評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門堵漱,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)综慎,“玉大人,你說(shuō)我怎么就攤上這事勤庐∈揪” “怎么了?”我有些...
    開封第一講書人閱讀 157,221評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵愉镰,是天一觀的道長(zhǎng)米罚。 經(jīng)常有香客問(wèn)我,道長(zhǎng)丈探,這世上最難降的妖魔是什么录择? 我笑而不...
    開封第一講書人閱讀 56,474評(píng)論 1 283
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上隘竭,老公的妹妹穿的比我還像新娘塘秦。我一直安慰自己,他們只是感情好货裹,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,570評(píng)論 6 386
  • 文/花漫 我一把揭開白布嗤形。 她就那樣靜靜地躺著,像睡著了一般弧圆。 火紅的嫁衣襯著肌膚如雪赋兵。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,816評(píng)論 1 290
  • 那天搔预,我揣著相機(jī)與錄音霹期,去河邊找鬼。 笑死拯田,一個(gè)胖子當(dāng)著我的面吹牛历造,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播船庇,決...
    沈念sama閱讀 38,957評(píng)論 3 408
  • 文/蒼蘭香墨 我猛地睜開眼吭产,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了鸭轮?” 一聲冷哼從身側(cè)響起臣淤,我...
    開封第一講書人閱讀 37,718評(píng)論 0 266
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎窃爷,沒想到半個(gè)月后邑蒋,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,176評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡按厘,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,511評(píng)論 2 327
  • 正文 我和宋清朗相戀三年医吊,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片逮京。...
    茶點(diǎn)故事閱讀 38,646評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡卿堂,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出懒棉,到底是詐尸還是另有隱情御吞,我是刑警寧澤,帶...
    沈念sama閱讀 34,322評(píng)論 4 330
  • 正文 年R本政府宣布漓藕,位于F島的核電站,受9級(jí)特大地震影響挟裂,放射性物質(zhì)發(fā)生泄漏享钞。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,934評(píng)論 3 313
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望栗竖。 院中可真熱鬧暑脆,春花似錦、人聲如沸狐肢。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,755評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)份名。三九已至碟联,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間僵腺,已是汗流浹背鲤孵。 一陣腳步聲響...
    開封第一講書人閱讀 31,987評(píng)論 1 266
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留辰如,地道東北人普监。 一個(gè)月前我還...
    沈念sama閱讀 46,358評(píng)論 2 360
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像琉兜,于是被迫代替她去往敵國(guó)和親凯正。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,514評(píng)論 2 348

推薦閱讀更多精彩內(nèi)容

  • Retrofit 2 源碼解析 關(guān)于Retrofit 2的使用請(qǐng)看上一篇https://www.jianshu.c...
    gogoingmonkey閱讀 512評(píng)論 0 1
  • 前言 注解式的框架非惩泱火廊散,注解以其輕量,簡(jiǎn)潔等特性被人們所喜愛者夺饲,關(guān)鍵是它解藕奸汇。網(wǎng)絡(luò)請(qǐng)求的框架非常多,比較受歡迎的...
    薩達(dá)哈魯醬閱讀 568評(píng)論 0 5
  • Retrofit是什么往声? 簡(jiǎn)介 Retrofit擂找,中文的翻譯為“式樣翻新”的意思,是一個(gè)基于OKHttp的REST...
    黃俊彬閱讀 1,349評(píng)論 0 8
  • 開始使用Retrofit 首先先聲明一個(gè)用于請(qǐng)求的接口 Converter.Factory factory = G...
    zyc_214閱讀 354評(píng)論 0 0
  • 本文將順著構(gòu)建請(qǐng)求對(duì)象->構(gòu)建請(qǐng)求接口->發(fā)起同步/異步請(qǐng)求的流程浩销,分析Retrofit是如何實(shí)現(xiàn)的贯涎。 開始之前,...
    zhuhf閱讀 1,610評(píng)論 0 10