国产黄色免费网站_久久天天做天天爱综合色_精品国产一区久久久_成人黄色激情网站_久久成人在线视频_美女一区二区在线观看_亚洲精品免费一区亚洲精品免费精品一区 _91精品国产综合久久精品麻豆

Retrofit源碼分析

2018-9-3    seo達人

如果您想訂閱本博客內容,每天自動發到您的郵箱中, 請點這里

1、簡介

retrofit是一個封裝okhttp請求的網絡請求庫,可以通過Rxjava適配返回信息。

2、原理分析

我們通過Retrofit.Builder建造者模式創建一個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方法創建一個Retrofit實例對象,在創建Retrofit時會判斷用戶創建OkhttpClient對象,沒有創建Retrofit會創建一個默認okhttpClient對象,然后設置Platform中的主線程線程池,設置線程池處理器交給主線程Looper對象。然后創建一個Retrofit對象。我們通過Retrofit.create創建一個接口代理類

 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

在調用Creater方法時,通過代理類創建Service實例對象,當我們通過接口實例對象調用方法時,通過invoke方法時,通過Method創建一個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

在創建ServiceMethod時,獲取我們okhttp請求是否有返回值,沒有返回值拋出異常,然后獲取注解信息,然后獲取retrofit中CallAdapter.Factory,然后調用get方法,我們在通過rxjavaFactoryAdapter.create創建的就是實現CallAdapter.Factory對象,然后調用CallAdapter.Factory中respenseType方法,然后通過我們傳遞converter對數據進行序列化,可以通過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

通過注解類型獲取到請求類型時,通過調用相關方法解析獲取到請求url,然后通過注解獲取方法中是否有注解字段,有注解信息存儲到Set集合中。然后創建一個OkhttpCall對象,通過調用serviceMethod.adapt方法做網絡請求,serviceMethod.adapt調用是callAdapter中的adapt方法,如果用戶沒有設置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中調用組裝的Call方法中enqueue方法調用異步網絡請求,成功后通過Platform中MainThreadExecutor切換到主線程。在調用callback中的enqueue,onResponse和onFairlure方法時實際是調用到OkhttpCall方法的onResponse方法,在OkHttpCall.enqueue中重新組建OkHttp.Call url和參數信息,然后封裝請求,請求成功后通過parseResponse解析返回信息狀態,然后把返回信息狀態成ResponseBody對象,調用ServiceMethod.toResponse解析,在toResponse中實際是我們設置ConverterFactory對象解析數據,完成后調用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();
            }
          }
        });
      }
藍藍設計www.newchinaweekly.com )是一家專注而深入的界面設計公司,為期望卓越的國內外企業提供卓越的UI界面設計、BS界面設計 、 cs界面設計 、 ipad界面設計 、 包裝設計 、 圖標定制 、 用戶體驗 、交互設計、 網站建設 平面設計服務

日歷

鏈接

個人資料

藍藍設計的小編 http://www.newchinaweekly.com

存檔

精品综合久久久久久8888| 日韩视频中午一区| 一本色道久久综合狠狠躁的推荐| 欧美午夜性色大片在线观看| gogogo免费视频观看亚洲一| 久久久一区二区三区| 亚洲精品videosex极品| 91香蕉视频污| 在线免费成人| 欧美激情99| 欧美9999| 亚洲成人激情社区| 精品亚洲免a| 欧美日韩精选| 99这里都是精品| 天天综合色天天| 岛国av午夜精品| 日韩精品中文字| 日本成人免费在线| 欧美专区在线观看| 日韩免费一区二区三区| 超碰在线人人爱| 欧美一级特黄高清视频| 成人性生交大免费看| 蜜臀精品一区二区三区| 青青青青国产视频| 中文字幕亚洲免费| 黄动漫在线免费观看| 在线视频se| 成人欧美大片| 亚洲成av人综合在线观看| 国产理论片在线观看| 日韩高清精品免费观看| 免费看91的网站| 欧美日本不卡视频| 麻豆传媒在线免费看| 僵尸再翻生在线观看免费国语| 久久久久久国产精品免费无遮挡| 亚洲一区二区三区精品中文字幕| 极品在线视频| 欧美日韩天堂| 国产精品色在线| 亚洲综合一区二区三区| 精品福利免费观看| 久久激情视频久久| 日韩美女主播视频| 91免费版看片| 最新日韩免费视频| 可以在线观看av的网站| 91极品身材尤物theporn| 在线a视频网站| 新版中文在线官网| 激情中国色综合| 亚洲在线成人| 91年精品国产| 日韩高清人体午夜| 精品国产91亚洲一区二区三区www| 小说区视频区图片区| 国产性生交xxxxx免费| 欧美日韩成人免费观看| 中文字幕人妻丝袜乱一区三区 | 少妇荡乳情欲办公室456视频| 亚洲av无一区二区三区久久| www.四虎精品| 91麻豆精品在线| 69ww免费视频播放器| 亚洲成人av高清| 丁香花在线影院| 亚洲视频狠狠| 99久久综合色| 日韩av一区二区在线| 精品乱色一区二区中文字幕| 亚洲天堂美女视频| 亚洲免费激情视频| 1插菊花综合| 亚洲精品在线播放| 综合久久精品| 国产一区二区久久| 精品国产乱码久久久久久老虎| 动漫美女被爆操久久久| 亚洲男女在线观看| 免费精品国产自产拍观看| 免费看男女www网站入口在线| 日韩在线黄色| 精品亚洲成a人在线观看| 夜夜嗨av一区二区三区中文字幕| 久久6免费高清热精品| 欧美亚洲国产成人| a视频免费在线观看| 精品黄色免费中文电影在线播放| 激情av一区| 6080国产精品一区二区| 国产亚洲精品自在久久| 三级a在线观看| 国产三级国产精品国产国在线观看| 91高清视频| 亚洲一区网址| 亚洲精品乱码久久久久久| 国产精品爱久久久久久久| 五月六月丁香婷婷| 国产情侣免费视频| 国产精品一区二区婷婷| 国产日韩免费| 日韩成人xxxx| 国产免费成人在线| 午夜精品福利在线视频| 狠狠干夜夜操| 欧美激情亚洲| 精品少妇一区二区三区在线视频| 在线观看成人一级片| 91美女精品网站| free性m.freesex欧美| 成人国产精品免费观看动漫 | 蜜桃一区二区| 天天射综合影视| 99国产在线观看| 国产精品久久久久久久妇| 五月婷婷在线视频| 精品欧美久久| 91精品久久久久久蜜臀| 99热一区二区三区| 天堂av资源在线| 中文字幕久久精品一区二区| 亚洲国产精品一区二区久久| 久久亚洲国产精品日日av夜夜| 亚洲永久无码7777kkk| 中文岛国精品亚洲一区| 超碰免费在线播放| 国产精品亚洲综合久久| 国产亚洲精品久久久久久牛牛 | 最新日韩免费视频| 香蕉国产在线| 欧美96一区二区免费视频| www.日韩系列| 99亚洲精品视频| 欧美亚洲精品在线观看| 欧美片网站免费| 91国偷自产一区二区开放时间| 亚洲欧洲精品在线| 久久午夜无码鲁丝片| а√天堂在线官网| 国产拍揄自揄精品视频麻豆| 欧美国产视频一区二区| 青青草自拍偷拍| av色图一区| 亚欧美中日韩视频| 欧美黑人视频一区| 日韩高清dvd碟片| 麻豆资源在线| 中文在线资源观看网站视频免费不卡 | 精品福利一区二区三区免费视频| 缅甸午夜性猛交xxxx| 91网站免费| 亚洲福利电影| 欧美黑人国产人伦爽爽爽| 九九精品在线观看视频| 蜜臀av国内免费精品久久久夜夜| 亚洲欧美日韩久久精品| 欧美巨大另类极品videosbest | 777视频在线| jizzjizz在线| 激情视频极品美女日韩| 69堂亚洲精品首页| 国产一区二区视频免费在线观看| 亚洲成人77777| 巨人精品**| 亚洲欧美中文字幕在线一区| 国产精品探花一区二区在线观看| av在线电影网| 亚洲女人****多毛耸耸8| 欧洲金发美女大战黑人| jizz在线播放| 国产福利精品一区二区| 久久九九热免费视频| 小向美奈子av| 日韩不卡视频在线观看| 日韩欧美国产综合一区| 国产曰肥老太婆无遮挡| 人妻va精品va欧美va| 久久精品高清| 91精品国产91久久久| 欧美bbbbbbbbbbbb精品| 欧美美女在线直播| 久久亚洲一区二区三区四区五区高 | 综合天堂av久久久久久久| 久久亚洲欧美日韩精品专区| 国产 欧美 日韩 在线| av在线国产精品| 一区二区三区高清国产| 日本少妇性高潮| 精品一区毛片| 欧美自拍大量在线观看| 亚洲av综合色区无码一二三区| 激情一区二区| 成人欧美一区二区三区视频| 国产偷窥洗澡视频| 成人精品小蝌蚪| 国产肥臀一区二区福利视频| aaa在线免费观看| 在线不卡一区二区|