<em id="09ttv"></em>
    <sup id="09ttv"><pre id="09ttv"></pre></sup>
    <dd id="09ttv"></dd>

        • Retrofit源碼分析

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

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

          1、簡(jiǎn)介

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

          2、原理分析

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

          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

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

           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í),通過(guò)代理類創(chuàng)建Service實(shí)例對(duì)象,當(dāng)我們通過(guò)接口實(shí)例對(duì)象調(diào)用方法時(shí),通過(guò)invoke方法時(shí),通過(guò)Method創(chuàng)建一個(gè)ServiceMethod對(duì)象,然后把ServiceMethod存儲(chǔ)起來(lái)

           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請(qǐng)求是否有返回值,沒(méi)有返回值拋出異常,然后獲取注解信息,然后獲取retrofit中CallAdapter.Factory,然后調(diào)用get方法,我們?cè)谕ㄟ^(guò)rxjavaFactoryAdapter.create創(chuàng)建的就是實(shí)現(xiàn)CallAdapter.Factory對(duì)象,然后調(diào)用CallAdapter.Factory中respenseType方法,然后通過(guò)我們傳遞converter對(duì)數(shù)據(jù)進(jìn)行序列化,可以通過(guò)gson和fastjson進(jìn)行實(shí)例化對(duì)象,然后通過(guò)parseMethodAnnomation解析請(qǐng)求類型

           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

          通過(guò)注解類型獲取到請(qǐng)求類型時(shí),通過(guò)調(diào)用相關(guān)方法解析獲取到請(qǐng)求url,然后通過(guò)注解獲取方法中是否有注解字段,有注解信息存儲(chǔ)到Set集合中。然后創(chuàng)建一個(gè)OkhttpCall對(duì)象,通過(guò)調(diào)用serviceMethod.adapt方法做網(wǎng)絡(luò)請(qǐng)求,serviceMethod.adapt調(diào)用是callAdapter中的adapt方法,如果用戶沒(méi)有設(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ò)請(qǐng)求,成功后通過(guò)Platform中MainThreadExecutor切換到主線程。在調(diào)用callback中的enqueue,onResponse和onFairlure方法時(shí)實(shí)際是調(diào)用到OkhttpCall方法的onResponse方法,在OkHttpCall.enqueue中重新組建OkHttp.Call url和參數(shù)信息,然后封裝請(qǐng)求,請(qǐng)求成功后通過(guò)parseResponse解析返回信息狀態(tài),然后把返回信息狀態(tài)成ResponseBody對(duì)象,調(diào)用ServiceMethod.toResponse解析,在toResponse中實(shí)際是我們?cè)O(shè)置ConverterFactory對(duì)象解析數(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.sdgs6788.com )是一家專注而深入的界面設(shè)計(jì)公司,為期望卓越的國(guó)內(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ù)

          日歷

          鏈接

          個(gè)人資料

          存檔

          国产精品久久久亚洲| 久久久久久毛片免费看| 久久综合久久伊人| 亚洲综合久久夜AV | 国产激情久久久久久熟女老人 | 狠狠色丁香久久婷婷综| 久久这里只精品国产99热| 久久福利青草精品资源站免费| 精品综合久久久久久97超人| 久久精品一区二区三区中文字幕| 亚洲精品无码久久毛片| 精品久久久噜噜噜久久久| 国产精品亚洲综合专区片高清久久久| 日本精品久久久久影院日本| 亚洲国产精品久久久天堂| 丁香久久婷婷国产午夜视频| 久久久无码精品亚洲日韩蜜臀浪潮| 91精品国产91久久久久福利| 久久久久人妻精品一区三寸蜜桃| 伊人久久大香线蕉av不变影院| 久久九九有精品国产23百花影院| 久久亚洲精品无码播放| 国产精品免费福利久久| 欧美久久天天综合香蕉伊| 亚洲级αV无码毛片久久精品| 久久久久无码精品| 久久精品男人影院| 伊人久久大香线蕉亚洲| 久久精品国产99久久香蕉| av无码久久久久不卡免费网站| 久久久久亚洲精品日久生情 | 日产精品久久久久久久| 久久久久这里只有精品 | 久久综合欧美成人| 久久久噜噜噜久久中文福利| 久久乐国产综合亚洲精品| segui久久国产精品| 97久久久精品综合88久久| 久久国产色av免费看| 久久国产AVJUST麻豆| 午夜肉伦伦影院久久精品免费看国产一区二区三区 |