国产精品爱久久久久久久小说,女人扒开腿让男人桶到爽 ,亚洲欧美国产双大乳头,国产成人精品综合久久久久,国产精品制服丝袜无码,免费无码精品黄av电影,黑色丝袜无码中中文字幕,乱熟女高潮一区二区在线

            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.dzxscac.cn )是一家專注而深入的界面設計公司,為期望卓越的國內外企業提供卓越的UI界面設計、BS界面設計 、 cs界面設計 、 ipad界面設計 、 包裝設計 、 圖標定制 、 用戶體驗 、交互設計、 網站建設 、平面設計服務。

            日歷

            鏈接

            個人資料

            藍藍設計的小編 http://www.dzxscac.cn

            存檔

            主站蜘蛛池模板: 大伊香蕉精品一区视频在线| 亚洲av永久纯肉无码精品动漫| 亚洲国产精品久久精品成人网站| 黄网在线免费观看| 伊人久久狼人| 双乳被四个男人吃奶h文| 精品在线免费观看视频| 亚洲精品乱码久久久久久按摩 | 日本一本二本三区免费| 亚洲精品日韩一区二区小说| 欧美aaaaaaaaa| 精品国产欧美一区二区 | 无码精品人妻一区二区三区湄公河| 青草青草视频2免费观看| 香蕉久久av一区二区三区app| 依依成人在线| 亚洲综合成人一区二区三区| av永久免费观看网站| 人人干人人干| 无码人妻久久一区二区三区不卡| 青娱乐极品视觉盛宴国产视频| 韩国19禁主播深夜福利视频| 日韩av激情| 999久久欧美人妻一区二区| 热久久视久久精品18| 久久国产区| 69色堂| 脱岳裙子从后面挺进去在线观看 | 精品人妻一区二区三区麻豆91| 亚洲s码欧洲m码国产av| 欧美丰满熟妇vaideos| 欧美日韩一区二区精品| 日本极品少妇videossexhd| 久久综合色一综合色88| 国产精品永久| 亚洲成人aaa| 青青青手机频在线观看| 边喂奶边中出的人妻| 亚洲色图清纯唯美| 色综合 图片区 小说区| 亚洲爆乳aaa无码专区|