国产精品美女久久久浪潮AV,国产精品三级一二三区,久久精品国产一区二区小说 ,依依成人影视国产精品,全部无卡免费的毛片在线看,日本一区二区三深夜不卡,国产精品女同一区二区久久,国产精品夜色一区二区三区

        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.shtzxx.cn )是一家專注而深入的界面設(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| 城固县| 亚洲伊人久久大香线蕉av| 天下第一社区在线观看| 久久99国产精品久久| 同江市| 久久无码专区国产精品| 麻花豆剧国产mv在视频播出| 男女18禁啪啪无遮挡激烈网站| 天祝| 女人与公狼做交十配视频| 久久精品国产一区二区三区不卡 | 安新县| 天美传媒mv免费观看完整| av不卡在线永久免费观看| 欧美人与zoxxxx另类| 亚洲熟妇少妇任你躁在线观看无码| 搡bbbb搡bbb搡五十| 精品国产粉嫩内射白浆内射双马尾| japane欧美孕交se孕妇孕交| 欧美高清俄罗斯极品| √天堂中文在线最新版| 国产精品va在线观看h| 无套内射蜜桃小视频| 午夜精品一区二区三区的区别| 蜜桃精品成人影片| 爱如潮水在线观看视频| 老师露双奶头无遮挡挤奶视频| 国产欧美精品aaaaaa片| 性色欲情网站iwww| 金寨县| 资中县| 亚洲欧美日韩综合在线网站 | 阜宁县| japane欧美孕交se孕妇孕交| 西西人体高清44rt·net|