嫩草影院久久99_老司机午夜网站国内精品久久久久久久久_久久夜色精品国产_国产一级做a爰片久久毛片

Retrofit源碼分析

2018-9-3    seo達人

如果您想訂閱本博客內(nèi)容,每天自動發(fā)到您的郵箱中, 請點這里

1、簡介

retrofit是一個封裝okhttp請求的網(wǎng)絡(luò)請求庫,可以通過Rxjava適配返回信息。

2、原理分析

我們通過Retrofit.Builder建造者模式創(chuàng)建一個Retrofit實例對象

public static final class Builder {
    /**
      *Android線程切換的類 
      */
    private final Platform platform;
    private @Nullable okhttp3.Call.Factory callFactory;
    private HttpUrl baseUrl;
    private final List<Converter.Factory> converterFactories = new ArrayList<>();
    private final List<CallAdapter.Factory> callAdapterFactories = new ArrayList<>();
    private @Nullable Executor callbackExecutor;
    private boolean validateEagerly;

    Builder(Platform platform) {
      this.platform = platform;
    }

    public Builder() {
      this(Platform.get());
    }

    Builder(Retrofit retrofit) {
      platform = Platform.get();
      callFactory = retrofit.callFactory;
      baseUrl = retrofit.baseUrl;

      converterFactories.addAll(retrofit.converterFactories);
      // Remove the default BuiltInConverters instance added by build().
      converterFactories.remove(0);

      callAdapterFactories.addAll(retrofit.callAdapterFactories);
      // Remove the default, platform-aware call adapter added by build().
      callAdapterFactories.remove(callAdapterFactories.size() - 1);

      callbackExecutor = retrofit.callbackExecutor;
      validateEagerly = retrofit.validateEagerly;
    }

    public Builder client(OkHttpClient client) {
      return callFactory(checkNotNull(client, "client == null"));
    }

    public Builder callFactory(okhttp3.Call.Factory factory) {
      this.callFactory = checkNotNull(factory, "factory == null");
      return this;
    }

    public Builder baseUrl(String baseUrl) {
      checkNotNull(baseUrl, "baseUrl == null");
      HttpUrl httpUrl = HttpUrl.parse(baseUrl);
      if (httpUrl == null) {
        throw new IllegalArgumentException("Illegal URL: " + baseUrl);
      }
      return baseUrl(httpUrl);
    }

    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;
    }

    public Builder addConverterFactory(Converter.Factory factory) {
      converterFactories.add(checkNotNull(factory, "factory == null"));
      return this;
    }

    public Builder addCallAdapterFactory(CallAdapter.Factory factory) {
      callAdapterFactories.add(checkNotNull(factory, "factory == null"));
      return this;
    }

    public Builder callbackExecutor(Executor executor) {
      this.callbackExecutor = checkNotNull(executor, "executor == null");
      return this;
    }

    public List<CallAdapter.Factory> callAdapterFactories() {
      return this.callAdapterFactories;
    }

    public List<Converter.Factory> converterFactories() {
      return this.converterFactories;
    }

    public Builder validateEagerly(boolean validateEagerly) {
      this.validateEagerly = validateEagerly;
      return this;
    }

    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.add(platform.defaultCallAdapterFactory(callbackExecutor));

      // Make a defensive copy of the converters.
      List<Converter.Factory> converterFactories =
          new ArrayList<>(1 + this.converterFactories.size());

      // 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);

      return new Retrofit(callFactory, baseUrl, unmodifiableList(converterFactories),
          unmodifiableList(callAdapterFactories), callbackExecutor, validateEagerly);
    }
 } 
    
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129

通過Retrofit.Builder中build方法創(chuàng)建一個Retrofit實例對象,在創(chuàng)建Retrofit時會判斷用戶創(chuàng)建OkhttpClient對象,沒有創(chuàng)建Retrofit會創(chuàng)建一個默認okhttpClient對象,然后設(shè)置Platform中的主線程線程池,設(shè)置線程池處理器交給主線程Looper對象。然后創(chuàng)建一個Retrofit對象。我們通過Retrofit.create創(chuàng)建一個接口代理類

 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();

          @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);
            }
            ServiceMethod<Object, Object> serviceMethod =
                (ServiceMethod<Object, Object>) loadServiceMethod(method);
            OkHttpCall<Object> okHttpCall = new OkHttpCall<>(serviceMethod, args);
            return serviceMethod.adapt(okHttpCall);
          }
        });
  } 
    
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26

在調(diào)用Creater方法時,通過代理類創(chuàng)建Service實例對象,當我們通過接口實例對象調(diào)用方法時,通過invoke方法時,通過Method創(chuàng)建一個ServiceMethod對象,然后把ServiceMethod存儲起來

 public ServiceMethod build() {
          callAdapter = createCallAdapter();
          responseType = callAdapter.responseType();
          if (responseType == Response.class || responseType == okhttp3.Response.class) {
            throw methodError("'"
                + Utils.getRawType(responseType).getName()
                + "' is not a valid response body type. Did you mean ResponseBody?");
          }
          responseConverter = createResponseConverter();

          for (Annotation annotation : methodAnnotations) {
            parseMethodAnnotation(annotation);
          }

          if (httpMethod == null) {
            throw methodError("HTTP method annotation is required (e.g., @GET, @POST, etc.).");
          }

          if (!hasBody) {
            if (isMultipart) {
              throw methodError(
                  "Multipart can only be specified on HTTP methods with request body (e.g., @POST).");
            }
            if (isFormEncoded) {
              throw methodError("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; p < parameterCount; p++) {
            Type parameterType = parameterTypes[p];
            if (Utils.hasUnresolvableType(parameterType)) {
              throw parameterError(p, "Parameter type must not include a type variable or wildcard: %s",
                  parameterType);
            }

            Annotation[] parameterAnnotations = parameterAnnotationsArray[p];
            if (parameterAnnotations == null) {
              throw parameterError(p, "No Retrofit annotation found.");
            }

            parameterHandlers[p] = parseParameter(p, parameterType, parameterAnnotations);
          }

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

          return new ServiceMethod<>(this);
        }

    private CallAdapter<T, R> createCallAdapter() {
            /**
             *獲取方法返回值類型
             */
          Type returnType = method.getGenericReturnType();
          if (Utils.hasUnresolvableType(returnType)) {
            throw methodError(
                "Method return type must not include a type variable or wildcard: %s", returnType);
          }
          if (returnType == void.class) {
            throw methodError("Service methods cannot return void.");
          }
          //獲取注解信息
          Annotation[] annotations = method.getAnnotations();
          try {
            //noinspection unchecked
            return (CallAdapter<T, R>) retrofit.callAdapter(returnType, annotations);
          } catch (RuntimeException e) { // Wide exception range because factories are user code.
            throw methodError(e, "Unable to create call adapter for %s", returnType);
          }
        } 
    
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85

在創(chuàng)建ServiceMethod時,獲取我們okhttp請求是否有返回值,沒有返回值拋出異常,然后獲取注解信息,然后獲取retrofit中CallAdapter.Factory,然后調(diào)用get方法,我們在通過rxjavaFactoryAdapter.create創(chuàng)建的就是實現(xiàn)CallAdapter.Factory對象,然后調(diào)用CallAdapter.Factory中respenseType方法,然后通過我們傳遞converter對數(shù)據(jù)進行序列化,可以通過gson和fastjson進行實例化對象,然后通過parseMethodAnnomation解析請求類型

 private void parseHttpMethodAndPath(String httpMethod, String value, boolean hasBody) {
          if (this.httpMethod != null) {
            throw methodError("Only one HTTP method is allowed. Found: %s and %s.",
                this.httpMethod, httpMethod);
          }
          this.httpMethod = httpMethod;
          this.hasBody = hasBody;

          if (value.isEmpty()) {
            return;
          }

          // Get the relative URL path and existing query string, if present.
          int question = value.indexOf('?');
          if (question != -1 && question < value.length() - 1) {
            // Ensure the query string does not have any named parameters.
            String queryParams = value.substring(question + 1);
            Matcher queryParamMatcher = PARAM_URL_REGEX.matcher(queryParams);
            if (queryParamMatcher.find()) {
              throw methodError("URL query string \"%s\" must not have replace block. "
                  + "For dynamic query parameters use @Query.", queryParams);
            }
          }

          this.relativeUrl = value;
          this.relativeUrlParamNames = parsePathParameters(value);
        } 
    
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28

通過注解類型獲取到請求類型時,通過調(diào)用相關(guān)方法解析獲取到請求url,然后通過注解獲取方法中是否有注解字段,有注解信息存儲到Set集合中。然后創(chuàng)建一個OkhttpCall對象,通過調(diào)用serviceMethod.adapt方法做網(wǎng)絡(luò)請求,serviceMethod.adapt調(diào)用是callAdapter中的adapt方法,如果用戶沒有設(shè)置callAdapter模式使用的是ExecutorCallAdapterFactory中的adapt方法

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

                    public Call<Object> adapt(Call<Object> call) {
                        return new ExecutorCallAdapterFactory.ExecutorCallbackCall(ExecutorCallAdapterFactory.this.callbackExecutor, call);
                    }
                };
            }
        } 
    
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

在ExectorCallAdapterFactory中調(diào)用組裝的Call方法中enqueue方法調(diào)用異步網(wǎng)絡(luò)請求,成功后通過Platform中MainThreadExecutor切換到主線程。在調(diào)用callback中的enqueue,onResponse和onFairlure方法時實際是調(diào)用到OkhttpCall方法的onResponse方法,在OkHttpCall.enqueue中重新組建OkHttp.Call url和參數(shù)信息,然后封裝請求,請求成功后通過parseResponse解析返回信息狀態(tài),然后把返回信息狀態(tài)成ResponseBody對象,調(diào)用ServiceMethod.toResponse解析,在toResponse中實際是我們設(shè)置ConverterFactory對象解析數(shù)據(jù),完成后調(diào)用callBack中onSuccess方法。

 @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 {
              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) {
              callFailure(e);
              return;
            }

            try {
              callback.onResponse(OkHttpCall.this, response);
            } catch (Throwable t) {
              t.printStackTrace();
            }
          }

          @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) {
              t.printStackTrace();
            }
          }
        });
      }
藍藍設(shè)計m.sdgs6788.com )是一家專注而深入的界面設(shè)計公司,為期望卓越的國內(nèi)外企業(yè)提供卓越的UI界面設(shè)計、BS界面設(shè)計 、 cs界面設(shè)計 、 ipad界面設(shè)計 、 包裝設(shè)計 、 圖標定制 、 用戶體驗 、交互設(shè)計、 網(wǎng)站建設(shè) 平面設(shè)計服務(wù)

日歷

鏈接

個人資料

藍藍設(shè)計的小編 http://m.sdgs6788.com

存檔

嫩草影院久久99_老司机午夜网站国内精品久久久久久久久_久久夜色精品国产_国产一级做a爰片久久毛片
<em id="09ttv"></em>
    <sup id="09ttv"><pre id="09ttv"></pre></sup>
    <dd id="09ttv"></dd>

        • 黑人一区二区三区四区五区| 欧美成人精品高清在线播放| 国产综合网站| 欧美日韩视频不卡| 欧美日韩国产高清| 国产精品狠色婷| 国产日韩精品电影| 欲色影视综合吧| 亚洲精品网站在线播放gif| 亚洲美女在线看| 一区二区三区精品视频| 亚洲在线视频免费观看| 香蕉久久一区二区不卡无毒影院| 欧美一级淫片aaaaaaa视频| 久久精品国产77777蜜臀| 麻豆av一区二区三区| 日韩午夜在线播放| 亚洲影视在线| 久久这里只有| 国产精品jvid在线观看蜜臀| 国产亚洲精品v| 99国产精品久久久久久久成人热| 午夜在线精品偷拍| 欧美激情偷拍| 欧美一区二区三区播放老司机| 蜜臀av在线播放一区二区三区| 国产精品青草久久| 亚洲激情二区| 久久久激情视频| 亚洲欧洲一区| 欧美亚洲视频| 欧美午夜在线视频| 亚洲国产一成人久久精品| 欧美一区亚洲一区| 亚洲精品综合在线| 久久免费黄色| 国产午夜精品一区理论片飘花| 亚洲免费电影在线| 免费成人网www| 亚洲欧美激情四射在线日 | 欧美精品成人| 国内精品视频一区| 午夜视频在线观看一区二区三区| 亚洲激情一区二区三区| 欧美在线亚洲一区| 国产精品网站在线观看| 亚洲午夜黄色| 亚洲毛片视频| 欧美精品免费在线观看| 亚洲黄色片网站| 裸体一区二区三区| 久久久久一区二区三区| 韩曰欧美视频免费观看| 久久精品免费播放| 欧美亚洲一区三区| 欧美在线播放高清精品| 国产精品高精视频免费| 一区二区三区免费看| 亚洲国产第一页| 蜜桃av一区二区三区| 亚洲二区精品| 欧美国产精品中文字幕| 欧美激情第一页xxx| 亚洲精品男同| 亚洲人成网站777色婷婷| 欧美h视频在线| 一本色道久久综合| 99精品视频免费观看视频| 欧美日韩国产一区二区三区| 宅男在线国产精品| 亚洲一区二区三区涩| 国产区在线观看成人精品| 久久久久久久久久看片| 久久免费国产| 一区二区欧美国产| 亚洲天堂男人| 韩国av一区| 亚洲人成高清| 国产精品欧美在线| 久久资源av| 欧美另类视频| 性久久久久久久久久久久| 欧美一区激情视频在线观看| 亚洲国产综合视频在线观看| 99视频精品免费观看| 国产欧美日韩另类一区 | 看欧美日韩国产| 久久深夜福利免费观看| 99精品国产在热久久婷婷| 亚洲一区二区毛片| 娇妻被交换粗又大又硬视频欧美| 欧美激情按摩| 国产精品一区二区黑丝| 欧美成人精品一区| 国产精品久久久久9999吃药| 麻豆国产精品va在线观看不卡| 欧美精品九九| 久久久噜噜噜| 欧美日韩视频在线观看一区二区三区| 欧美制服第一页| 欧美激情一区二区三级高清视频| 亚洲欧美电影院| 美女亚洲精品| 久久大综合网| 欧美日韩色一区| 美玉足脚交一区二区三区图片| 欧美日韩国产综合视频在线观看 | 欧美黄色大片网站| 欧美一区二区在线免费观看| 欧美精品在线极品| 久久亚洲精品伦理| 国产精品家教| 亚洲国产午夜| 在线观看国产日韩| 午夜亚洲性色福利视频| 国产精品久久久久久久久借妻| 久久综合久久综合久久综合| 国产精品美女一区二区| 亚洲国产精品123| 黄色工厂这里只有精品| 亚洲一区尤物| 亚洲曰本av电影| 欧美日韩日本国产亚洲在线| 欧美国产第一页| 亚洲第一中文字幕| 午夜视频一区在线观看| 午夜宅男欧美| 国产精品久久久久免费a∨大胸| 亚洲欧洲精品一区二区三区| 亚洲高清不卡av| 久久亚洲综合色| 美女精品在线观看| 好吊色欧美一区二区三区视频| 亚洲欧美日韩天堂一区二区| 亚洲欧美一区二区精品久久久| 欧美日韩综合另类| 99热在线精品观看| 亚洲欧美另类国产| 国产精品区一区二区三区| 亚洲午夜伦理| 久久精品日产第一区二区| 国产亚洲高清视频| 欧美一级久久久久久久大片| 久久本道综合色狠狠五月| 国产视频亚洲精品| 久久精品99久久香蕉国产色戒| 美女精品视频一区| 亚洲国产一成人久久精品| 欧美激情一区二区三区不卡| 亚洲精品在线一区二区| 午夜精品久久久久久久久久久久久| 国产精品黄色在线观看| 午夜一级在线看亚洲| 女生裸体视频一区二区三区| 亚洲精品综合久久中文字幕| 欧美日韩一区二| 午夜精品视频| 欧美激情 亚洲a∨综合| 亚洲一区二区三区中文字幕| 国产视频一区在线观看| 久久午夜国产精品| 亚洲精品一品区二品区三品区| 亚洲字幕一区二区| 激情婷婷久久| 欧美日韩在线一二三| 欧美一区国产二区| 亚洲激情一区| 欧美亚洲视频在线看网址| 一区精品在线播放| 欧美日韩在线不卡| 欧美在线视频免费播放| 91久久亚洲| 久久天堂成人| 一区二区三区你懂的| 国内自拍亚洲| 国产精品成人在线观看| 久久久欧美一区二区| 一区二区毛片| 欧美成人小视频| 香蕉久久夜色精品| 亚洲精品免费网站| 国产欧美一区二区视频| 欧美激情导航| 久久久久久久高潮| 亚洲在线网站| 日韩一级在线| 亚洲国产精品一区二区尤物区| 久久精品国产一区二区三区免费看| 欧美日韩四区| 牛牛影视久久网| 欧美一区二区日韩| 一本色道久久综合狠狠躁篇的优点| 米奇777在线欧美播放| 欧美一区二区三区视频免费| 99国产精品| 亚洲精品国产精品国自产观看| 国模精品娜娜一二三区| 国产精品亚洲综合色区韩国| 国产精品福利久久久| 欧美日韩八区|