美文网首页
Retrofit(七)--OkHttpCall

Retrofit(七)--OkHttpCall

作者: azu_test | 来源:发表于2019-03-01 15:10 被阅读0次

    移步Retrofit--网络通讯框架

    OkHttpCall的工作

    • 通过ServiceMethod生成真正的OkHttp#Call
    • 通过OkHttp#Call做真正的网络请求
    • 返回的网络数据通过ServiceMethod解析成我们需要的类型

    源码分析

    1. 初始化的入口

              @Override public Object invoke(Object proxy, Method method, @Nullable Object[] args)
                  throws Throwable {
                ...
                ServiceMethod<Object, Object> serviceMethod =
                    (ServiceMethod<Object, Object>) loadServiceMethod(method);
                //入口
                OkHttpCall<Object> okHttpCall = new OkHttpCall<>(serviceMethod, args);
                return serviceMethod.adapt(okHttpCall);
              }
    

    通过serviceMethod和参数值创建OkHttpCall

    2. 构造方法

      OkHttpCall(ServiceMethod<T, ?> serviceMethod, @Nullable Object[] args) {
        this.serviceMethod = serviceMethod;
        this.args = args;
      }
    

    持有serviceMethod对象和args请求参数值

    3. 获取真正的网络请求对象OkHttp#Call

      OkHttpCall#createRawCall
      private okhttp3.Call createRawCall() throws IOException {
        okhttp3.Call call = serviceMethod.toCall(args);
        if (call == null) {
          throw new NullPointerException("Call.Factory returned null.");
        }
        return call;
      }
    

    通过serviceMethod.toCall获取真正的网络请求对象OkHttp#Call

    4. 解析网络返回数据

      Response<T> parseResponse(okhttp3.Response rawResponse) throws IOException {
        ResponseBody rawBody = rawResponse.body();
    
        // Remove the body's source (the only stateful object) so we can pass the response along.
        rawResponse = rawResponse.newBuilder()
            .body(new NoContentResponseBody(rawBody.contentType(), rawBody.contentLength()))
            .build();
    
        int code = rawResponse.code();
        if (code < 200 || code >= 300) {
          try {
            // Buffer the entire body to avoid future I/O.
            ResponseBody bufferedBody = Utils.buffer(rawBody);
            return Response.error(bufferedBody, rawResponse);
          } finally {
            rawBody.close();
          }
        }
    
        if (code == 204 || code == 205) {
          rawBody.close();
          return Response.success(null, rawResponse);
        }
    
        ExceptionCatchingRequestBody catchingBody = new ExceptionCatchingRequestBody(rawBody);
        try {
          //真正做数据解析操作的地方
          T body = serviceMethod.toResponse(catchingBody);
          return Response.success(body, rawResponse);
        } catch (RuntimeException e) {
          // If the underlying source threw an exception, propagate that rather than indicating it was
          // a runtime exception.
          catchingBody.throwIfCaught();
          throw e;
        }
      }
    

    5. 执行网络请求

      @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 {
              //获取真正的网络请求`OkHttp#Call`
              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 {
              //回调给ExecutorCallbackCall.enqueue()
              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();
            }
          }
        });
      }
    

    上面的方法主要工作是

    1. 获取真正的网络请求OkHttp#Call
    2. OkHttp#Call.enqueue()获取网络请求结果
    3. 解析网络请求结果并返回至ExecutorCallbackCall

    相关文章

      网友评论

          本文标题:Retrofit(七)--OkHttpCall

          本文链接:https://www.haomeiwen.com/subject/xneduqtx.html