1. 程式人生 > >Retrofit與RxJava和OKhttp對接

Retrofit與RxJava和OKhttp對接

Retrofit在整個網路請求架構(Rxjava+Retrofit+OKhttp)的位置處於一箇中間連線的環節,非同步解耦層是Rxjava,網路請求層是OKhttp。

那Retrofit是如何與二者進行對接的,本人菜鳥,在這裡寫一下自己的理解,如有不合理之處,懇請指正。

一、與OKhttp相互對接

Retrofit中的Call介面:

public interface Call<T> extends Cloneable {

   Response execute()throws IOException;//同步請求方法

   void enqueue(Callback callback);//非同步請求方法
  
   /******/

}

比較重要的就是同步和非同步請求,與OKhttp對接的網路請求類是

final class OkHttpCall<T> implements Call<T>

首先看一下同步方法請求:

@Override public Response<T> execute() throws IOException {
    okhttp3.Call call;//Okhttp中的Call類,用於真正的網路請求

    synchronized (this) {
      if (executed) throw new IllegalStateException("Already executed.");
      executed = true;

      if (creationFailure != null) {
        if (creationFailure instanceof IOException) {
          throw (IOException) creationFailure;
        } else {
          throw (RuntimeException) creationFailure;
        }
      }

      call = rawCall;
      if (call == null) {
        try {
          call = rawCall = createRawCall();
        } catch (IOException | RuntimeException e) {
          creationFailure = e;
          throw e;
        }
      }
    }

    if (canceled) {
      call.cancel();
    }

    return parseResponse(call.execute());//返回Okhttp中call的同步請求結果,會堵塞當前執行緒
  }

在原始碼中發現,retrofit中使用Call同步請求網路訪問其實最終調起的也是OKhttp中的call的同步請求,只是將OKhttp的請求結果進行進一步的封裝和處理。

下面看一下Retrofit非同步請求的原始碼

  @Override public void enqueue(final Callback<T> callback) {
    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) {
          failure = creationFailure = t;
        }
      }
    }

    if (failure != null) {
      callback.onFailure(this, failure);
      return;
    }

    if (canceled) {
      call.cancel();
    }

    call.enqueue(new okhttp3.Callback() {//跟同步請求相似,也是調起OKhttp的非同步請求
      @Override public void onResponse(okhttp3.Call call, okhttp3.Response rawResponse)
          throws IOException {
        Response<T> response;
        try {
          response = parseResponse(rawResponse);
        } catch (Throwable e) {
          callFailure(e);
          return;
        }
        callSuccess(response);
      }

      @Override public void onFailure(okhttp3.Call call, IOException e) {
        try {
          callback.onFailure(OkHttpCall.this, e);
        } catch (Throwable t) {
          t.printStackTrace();
        }
      }

      private void callFailure(Throwable e) {
        try {
          callback.onFailure(OkHttpCall.this, e);
        } catch (Throwable t) {
          t.printStackTrace();
        }
      }

      private void callSuccess(Response<T> response) {
        try {
          callback.onResponse(OkHttpCall.this, response);
        } catch (Throwable t) {
          t.printStackTrace();
        }
      }
    });
  }

從原始碼中可以看出,跟同步請求類似,Retrofit是調起的OKhttp中的非同步請求方法: call.enqueue。