• <center id="sm46c"></center>
  • <dfn id="sm46c"></dfn>
  • <strike id="sm46c"></strike>
  • <cite id="sm46c"><source id="sm46c"></source></cite>
    • <strike id="sm46c"><source id="sm46c"></source></strike>
      <option id="sm46c"></option>
      国产精品天天看天天狠,女高中生强奷系列在线播放,久久无码免费的a毛片大全,国产日韩综合av在线,亚洲国产中文综合专区在,特殊重囗味sm在线观看无码,中文字幕一区二区三区四区在线,无码任你躁久久久久久老妇蜜桃

      Retrofit源碼分析

      2018-9-3    seo達(dá)人

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

      1、簡介

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

      2、原理分析

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

      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實(shí)例對象,在創(chuàng)建Retrofit時(shí)會判斷用戶創(chuàng)建OkhttpClient對象,沒有創(chuàng)建Retrofit會創(chuàng)建一個默認(rèn)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方法時(shí),通過代理類創(chuàng)建Service實(shí)例對象,當(dāng)我們通過接口實(shí)例對象調(diào)用方法時(shí),通過invoke方法時(shí),通過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時(shí),獲取我們okhttp請求是否有返回值,沒有返回值拋出異常,然后獲取注解信息,然后獲取retrofit中CallAdapter.Factory,然后調(diào)用get方法,我們在通過rxjavaFactoryAdapter.create創(chuàng)建的就是實(shí)現(xiàn)CallAdapter.Factory對象,然后調(diào)用CallAdapter.Factory中respenseType方法,然后通過我們傳遞converter對數(shù)據(jù)進(jìn)行序列化,可以通過gson和fastjson進(jìn)行實(shí)例化對象,然后通過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

      通過注解類型獲取到請求類型時(shí),通過調(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方法時(shí)實(shí)際是調(diào)用到OkhttpCall方法的onResponse方法,在OkHttpCall.enqueue中重新組建OkHttp.Call url和參數(shù)信息,然后封裝請求,請求成功后通過parseResponse解析返回信息狀態(tài),然后把返回信息狀態(tài)成ResponseBody對象,調(diào)用ServiceMethod.toResponse解析,在toResponse中實(shí)際是我們設(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();
                  }
                }
              });
            }
      藍(lán)藍(lán)設(shè)計(jì)www.li-bodun.cn )是一家專注而深入的界面設(shè)計(jì)公司,為期望卓越的國內(nèi)外企業(yè)提供卓越的UI界面設(shè)計(jì)、BS界面設(shè)計(jì) 、 cs界面設(shè)計(jì) 、 ipad界面設(shè)計(jì) 、 包裝設(shè)計(jì) 、 圖標(biāo)定制 、 用戶體驗(yàn) 、交互設(shè)計(jì)、 網(wǎng)站建設(shè) 平面設(shè)計(jì)服務(wù)

      日歷

      鏈接

      個人資料

      存檔

      主站蜘蛛池模板: 一本大道AV人久久综合| 亚洲日韩VA无码中文字幕| 国产在线一区二区香蕉 在线| 日韩在线视频线观看一区| 欧美成人怡红院一区二区| 色无码| 国产亚洲真人做受在线观看| 72种姿势欧美久久久久大黄蕉| 爆乳熟妇一区二区三区霸乳| 狠狠精品久久久无码中文字幕| 扎囊县| 久久国产av影片| 久久精品国产久精国产果冻传媒| 经典国产乱子伦精品视频| 亚洲人成电影在线观看天堂色| 台中市| 亚洲一区二区三区无码久久| 亚洲熟妇久久精品| 国产偷拍自拍视频在线观看| 国外欧美一区另类中文字幕| 国产亚洲精品久久久久秋霞不卡| 久久免费看少妇免费观看| 无码不卡中文字幕av| 激情文学另类小说亚洲图片| 日韩免费无码专区精品观看 | 无码中文字幕日韩专区| 2020国产激情视频在线观看| 柳江县| 舟山市| 亚洲成a人片在线观看88| 国产欧美在线一区二区三| 欧洲亚洲国内老熟女超碰| 枣阳市| 精品综合久久久久久888| 国产婷婷综合在线视频| 邓州市| av深夜福利在线| 一区二区三区四区在线不卡高清| 国产精品午夜福利麻豆| 久久精品国产99精品国产2021| 性色av无码无在线观看|